|
from fastapi.middleware.cors import CORSMiddleware |
|
from fastapi.staticfiles import StaticFiles |
|
from fastapi import FastAPI, APIRouter |
|
import base64, json, zipfile, uvicorn |
|
from strgen import StringGenerator |
|
from pydantic import BaseModel |
|
from pathlib import Path |
|
from io import BytesIO |
|
from PIL import Image |
|
|
|
app = FastAPI() |
|
|
|
app.add_middleware( |
|
CORSMiddleware, |
|
allow_origins=["*"], |
|
allow_credentials=True, |
|
allow_methods=["*"], |
|
allow_headers=["*"], |
|
) |
|
|
|
router = APIRouter() |
|
processing = False |
|
|
|
class TextRequest(BaseModel): text: str |
|
|
|
@router.post('/save') |
|
async def save(req_data: TextRequest): |
|
data = json.loads(req_data.text) |
|
zip_buffer = BytesIO() |
|
|
|
with zipfile.ZipFile(zip_buffer, 'w') as zip_file: |
|
zip_file.writestr('data.xml', data[0].encode('utf-8')) |
|
zip_file.writestr('data.txt', data[1].encode('utf-8')) |
|
|
|
for i in range(2, len(data)): |
|
file_data = base64.b64decode(data[i].split(',', 1)[1]) |
|
file_name = f'{i - 1}.{data[i].split(";")[0].split("/")[1]}' |
|
zip_file.writestr(file_name, file_data) |
|
|
|
zip_buffer.seek(0) |
|
return base64.b64encode(zip_buffer.getvalue()).decode('utf-8') |
|
|
|
@router.post('/load') |
|
async def load(zip_data: TextRequest): |
|
zip_buffer = BytesIO(base64.b64decode(zip_data.text)) |
|
data = [] |
|
with zipfile.ZipFile(zip_buffer, 'r') as zip_file: |
|
data.append(zip_file.open('data.xml').read().decode('utf-8')) |
|
data.append(zip_file.open('data.txt').read().decode('utf-8')) |
|
|
|
for file_info in zip_file.infolist(): |
|
if file_info.filename.startswith('data.'): continue |
|
with zip_file.open(file_info) as f: |
|
ext = file_info.filename.split('.')[-1] |
|
url = base64.b64encode(f.read()).decode('utf-8') |
|
data.append(f'data:image/{ext};base64,{url}') |
|
|
|
return data |
|
|
|
@router.get('/check') |
|
async def check(): |
|
global processing |
|
return 'ng' if processing else 'ok' |
|
|
|
@router.post('/sb3') |
|
async def sb3(req_data: TextRequest): |
|
global processing |
|
if processing: return '' |
|
processing = True |
|
data = json.loads(req_data.text) |
|
with zipfile.ZipFile(Path('public').joinpath('mmp4.zip').resolve(), 'r') as template_zip: |
|
with template_zip.open('project.json') as f: |
|
project = json.loads(f.read().decode('utf-8')) |
|
|
|
|
|
zip_buffer = BytesIO() |
|
with zipfile.ZipFile(zip_buffer, 'w') as zip_file: |
|
variables = project['targets'][0]['variables'] |
|
tiles = project['targets'].index([v for v in project['targets'] if v['name'] == 'Tiles'][0]) |
|
|
|
project['targets'][0]['variables'][[v for v in variables if variables[v][0] == 'MODコード'][0]][1] = data[0] |
|
|
|
names = StringGenerator('[a-f\\d]{32}').render_list(len(data) - 1, unique=True) |
|
for i in range(1, len(data)): |
|
name = f'{names[i - 1]}.png' |
|
image_data = base64.b64decode(data[i].split(',', 1)[1]) |
|
|
|
|
|
img = Image.open(BytesIO(image_data)) |
|
img_resized = img.resize((80, 80)) |
|
img_buffer = BytesIO() |
|
img_resized.save(img_buffer, format='PNG') |
|
img_buffer.seek(0) |
|
|
|
|
|
zip_file.writestr(name, img_buffer.getvalue()) |
|
|
|
project['targets'][tiles]['costumes'].append({ |
|
"name": str(i), |
|
"bitmapResolution": 2, |
|
"dataFormat": "png", |
|
"assetId": names[i - 1], |
|
"md5ext": f"{names[i - 1]}.png", |
|
"rotationCenterX": 40, |
|
"rotationCenterY": 40 |
|
}) |
|
|
|
|
|
zip_file.writestr('project.json', json.dumps(project).encode('utf-8')) |
|
|
|
|
|
with zipfile.ZipFile(Path('public').joinpath('mmp4.zip').resolve(), 'r') as template_zip: |
|
for item in template_zip.infolist(): |
|
if item.filename != 'project.json': |
|
zip_file.writestr(item.filename, template_zip.read(item.filename)) |
|
|
|
|
|
zip_buffer.seek(0) |
|
sb3_base64 = base64.b64encode(zip_buffer.getvalue()).decode('utf-8') |
|
|
|
processing = False |
|
return sb3_base64 |
|
|
|
app.include_router(router, prefix='/api') |
|
|
|
if __name__ == '__main__': |
|
app.mount('/', StaticFiles(directory=Path('public'), html=True), name='public') |
|
uvicorn.run(app, host='0.0.0.0', port=7860) |