This commit is contained in:
2026-05-26 20:16:08 +03:00
commit 302b09a4f7
4 changed files with 777 additions and 0 deletions
+178
View File
@@ -0,0 +1,178 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Сервер для управления данными бизнес-объединений ДНР.
Поддерживает:
- GET /data.json - получение данных
- POST /save - сохранение данных в файл
- POST /reset - сброс к дефолтным данным (загружает из data.default.json)
"""
import http.server
import socketserver
import json
import os
import shutil
from urllib.parse import urlparse
PORT = 8092
DATA_FILE = 'data.json'
DEFAULT_DATA_FILE = 'data.default.json'
# Дефолтные данные вынесены в отдельный файл data.default.json
# Если нужно создать файл с дефолтом - раскомментировать функцию ниже
class CustomHTTPRequestHandler(http.server.SimpleHTTPRequestHandler):
def end_headers(self):
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()
def do_OPTIONS(self):
self.send_response(200)
self.end_headers()
def do_GET(self):
parsed_path = urlparse(self.path)
# Отдаём data.json
if parsed_path.path == '/data.json':
self.send_response(200)
self.send_header('Content-Type', 'application/json; charset=utf-8')
self.end_headers()
try:
with open(DATA_FILE, 'r', encoding='utf-8') as f:
self.wfile.write(f.read().encode('utf-8'))
except FileNotFoundError:
self.send_error(404, 'data.json not found')
return
# Отдаём index.html
if parsed_path.path == '/' or parsed_path.path == '/index.html':
self.path = '/index.html'
# Статические файлы
if self.path.endswith('.html'):
self.send_response(200)
self.send_header('Content-Type', 'text/html; charset=utf-8')
self.end_headers()
try:
with open(self.path[1:], 'rb') as f:
self.wfile.write(f.read())
except FileNotFoundError:
self.send_error(404, 'File not found')
return
super().do_GET()
def do_POST(self):
parsed_path = urlparse(self.path)
# Сохранение данных
if parsed_path.path == '/save':
content_length = int(self.headers.get('Content-Length', 0))
post_data = self.rfile.read(content_length)
try:
data = json.loads(post_data.decode('utf-8'))
with open(DATA_FILE, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
response = json.dumps({'success': True, 'message': 'Данные сохранены'})
self.wfile.write(response.encode('utf-8'))
except json.JSONDecodeError as e:
self.send_response(400)
self.send_header('Content-Type', 'application/json')
self.end_headers()
response = json.dumps({'success': False, 'message': f'Ошибка JSON: {str(e)}'})
self.wfile.write(response.encode('utf-8'))
except Exception as e:
self.send_response(500)
self.send_header('Content-Type', 'application/json')
self.end_headers()
response = json.dumps({'success': False, 'message': f'Ошибка сервера: {str(e)}'})
self.wfile.write(response.encode('utf-8'))
return
# Сброс к дефолту (если есть файл data.default.json)
if parsed_path.path == '/reset':
try:
if os.path.exists(DEFAULT_DATA_FILE):
shutil.copy(DEFAULT_DATA_FILE, DATA_FILE)
self.send_response(200)
self.send_header('Content-Type', 'application/json')
self.end_headers()
response = json.dumps({'success': True, 'message': 'Данные сброшены к исходным'})
self.wfile.write(response.encode('utf-8'))
else:
self.send_response(404)
self.send_header('Content-Type', 'application/json')
self.end_headers()
response = json.dumps({'success': False, 'message': 'Файл с дефолтными данными не найден'})
self.wfile.write(response.encode('utf-8'))
except Exception as e:
self.send_response(500)
self.send_header('Content-Type', 'application/json')
self.end_headers()
response = json.dumps({'success': False, 'message': str(e)})
self.wfile.write(response.encode('utf-8'))
return
self.send_response(404)
self.end_headers()
def log_message(self, format, *args):
print(f"[{self.address_string()}] {format % args}")
def ensure_data_file():
"""Проверяет наличие data.json, если нет - создаёт из дефолта или пустой"""
if not os.path.exists(DATA_FILE):
if os.path.exists(DEFAULT_DATA_FILE):
shutil.copy(DEFAULT_DATA_FILE, DATA_FILE)
print(f"📄 Создан файл данных из {DEFAULT_DATA_FILE}")
else:
# Создаём минимальный пустой файл
empty_data = {
"organizations": [],
"additionalOrganizations": [],
"metadata": {"lastUpdated": "2026-01-15", "totalOrganizations": 0}
}
with open(DATA_FILE, 'w', encoding='utf-8') as f:
json.dump(empty_data, f, ensure_ascii=False, indent=2)
print(f"📄 Создан пустой файл данных: {DATA_FILE}")
print(f"⚠️ Для работы с данными создайте файл {DEFAULT_DATA_FILE} с дефолтными данными")
def run_server():
os.chdir(os.path.dirname(os.path.abspath(__file__)))
ensure_data_file()
with socketserver.TCPServer(("", PORT), CustomHTTPRequestHandler) as httpd:
print("=" * 60)
print(f"🚀 Сервер запущен!")
print(f"📁 Директория: {os.getcwd()}")
print(f"🌐 Локальный доступ: http://localhost:{PORT}")
print(f"📄 Файл данных: {DATA_FILE}")
print(f"📄 Дефолтный файл (если есть): {DEFAULT_DATA_FILE}")
print(f"⏹️ Для остановки сервера нажмите Ctrl+C")
print("=" * 60)
try:
httpd.serve_forever()
except KeyboardInterrupt:
print("\n🛑 Сервер остановлен.")
httpd.shutdown()
if __name__ == "__main__":
run_server()