Spaces:
Build error
Build error
File size: 5,912 Bytes
629446c | 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 | import os
import json
import zipfile
import shutil
import subprocess
import tempfile
from pathlib import Path
from typing import Dict, List, Optional
import threading
import time
from http.server import HTTPServer, SimpleHTTPRequestHandler
import socket
class FileHandler:
"""Handle file operations for website projects"""
def __init__(self):
self.projects_dir = Path("projects")
self.projects_dir.mkdir(exist_ok=True)
def create_project(self, project_name: str, files: Dict[str, str]) -> Path:
"""Create a new project with generated files"""
project_path = self.projects_dir / project_name
# Remove existing project if it exists
if project_path.exists():
shutil.rmtree(project_path)
project_path.mkdir(exist_ok=True)
# Write all files
for file_path, content in files.items():
full_path = project_path / file_path
full_path.parent.mkdir(parents=True, exist_ok=True)
with open(full_path, 'w', encoding='utf-8') as f:
f.write(content)
return project_path
def get_project_files(self, project_path: Path) -> Dict[str, str]:
"""Get all files in a project"""
files = {}
if project_path.exists():
for file_path in project_path.rglob("*"):
if file_path.is_file():
relative_path = file_path.relative_to(project_path)
files[str(relative_path)] = self.get_file_content(project_path, str(relative_path))
return files
def get_file_content(self, project_path: Path, filename: str) -> str:
"""Get content of a specific file"""
file_path = project_path / filename
if file_path.exists():
with open(file_path, 'r', encoding='utf-8') as f:
return f.read()
return ""
def create_zip(self, project_path: Path) -> str:
"""Create a ZIP file of the project"""
zip_path = f"{project_path}.zip"
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
for file_path in project_path.rglob("*"):
if file_path.is_file():
arcname = file_path.relative_to(project_path.parent)
zipf.write(file_path, arcname)
return zip_path
class PreviewManager:
"""Manage live preview of websites"""
def __init__(self):
self.active_servers = {}
self.port_counter = 8000
def get_free_port(self) -> int:
"""Find a free port for the preview server"""
while True:
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(('localhost', self.port_counter))
return self.port_counter
except OSError:
self.port_counter += 1
def create_preview(self, project_path: Path) -> str:
"""Create a live preview server for the project"""
port = self.get_free_port()
# Start server in a separate thread
server_thread = threading.Thread(
target=self._run_server,
args=(project_path, port),
daemon=True
)
server_thread.start()
# Give server time to start
time.sleep(0.5)
self.active_servers[str(project_path)] = port
return f"http://localhost:{port}"
def update_preview(self, project_path: Path) -> str:
"""Update the preview (server already running)"""
if str(project_path) in self.active_servers:
port = self.active_servers[str(project_path)]
return f"http://localhost:{port}"
return self.create_preview(project_path)
def _run_server(self, project_path: Path, port: int):
"""Run HTTP server for preview"""
os.chdir(project_path)
class CustomHandler(SimpleHTTPRequestHandler):
def __init__(self, *args, **kwargs):
super().__init__(*args, directory=project_path, **kwargs)
def end_headers(self):
# Add CORS headers
self.send_header('Access-Control-Allow-Origin', '*')
self.send_header('Access-Control-Allow-Methods', 'GET, POST, OPTIONS')
self.send_header('Access-Control-Allow-Headers', 'Content-Type')
super().end_headers()
try:
httpd = HTTPServer(('localhost', port), CustomHandler)
httpd.serve_forever()
except Exception as e:
print(f"Server error: {e}")
def detect_file_language(filename: str) -> str:
"""Detect programming language from file extension"""
ext = Path(filename).suffix.lower()
lang_map = {
'.html': 'html',
'.css': 'css',
'.js': 'javascript',
'.json': 'json',
'.md': 'markdown',
'.py': 'python',
'.jsx': 'jsx',
'.tsx': 'typescript',
'.ts': 'typescript',
'.xml': 'xml',
'.yaml': 'yaml',
'.yml': 'yaml',
'.sql': 'sql',
'.php': 'php',
'.rb': 'ruby',
'.go': 'go',
'.java': 'java',
'.c': 'c',
'.cpp': 'cpp',
'.h': 'c',
'.hpp': 'cpp',
'.scss': 'scss',
'.sass': 'sass',
'.less': 'less',
'.vue': 'vue',
'.svelte': 'svelte'
}
return lang_map.get(ext, 'text')
def format_file_size(size_bytes: int) -> str:
"""Format file size in human readable format"""
if size_bytes == 0:
return "0B"
size_names = ["B", "KB", "MB", "GB"]
i = 0
while size_bytes >= 1024 and i < len(size_names) - 1:
size_bytes /= 1024.0
i += 1
return f"{size_bytes:.1f}{size_names[i]}" |