142 lines
5.0 KiB
Python
142 lines
5.0 KiB
Python
import json, os, uuid
|
|
from datetime import datetime
|
|
|
|
with open('app/routes.py', 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
|
|
prefix = """import json
|
|
import uuid
|
|
import os
|
|
"""
|
|
|
|
functions = """
|
|
def get_bed_dimensions():
|
|
try:
|
|
from flask import current_app
|
|
path = os.path.join(current_app.root_path, '..', 'print_config', 'printers', 'creality_ender3v3se.def.json')
|
|
with open(path, 'r', encoding='utf-8') as f:
|
|
data = json.load(f)
|
|
w = data['overrides']['machine_width']['default_value']
|
|
h = data['overrides']['machine_depth']['default_value']
|
|
hd = data['overrides']['machine_height']['default_value']
|
|
return w, h, hd
|
|
except:
|
|
return 200, 200, 200
|
|
|
|
def get_quality_presets():
|
|
try:
|
|
from flask import current_app
|
|
path = os.path.join(current_app.root_path, '..', 'print_config', 'presets', 'creality', 'base')
|
|
files = [f for f in os.listdir(path) if f.endswith('.inst.cfg')]
|
|
presets = []
|
|
for f in files:
|
|
name = f.replace('.inst.cfg', '').replace('base_', '').replace('_', ' ')
|
|
presets.append((f, name))
|
|
return presets
|
|
except:
|
|
return []
|
|
"""
|
|
|
|
routes = """
|
|
@main_bp.route('/plater')
|
|
@login_required
|
|
def plater():
|
|
w, h, hd = get_bed_dimensions()
|
|
presets = get_quality_presets()
|
|
last_quality = request.cookies.get('last_quality_preset', 'base_global_standard.inst.cfg')
|
|
user_files = PrintFile.query.filter_by(user_id=current_user.id, file_type='stl').order_by(PrintFile.created_at.desc()).all()
|
|
models = [{'id': f.id, 'name': f.original_filename, 'url': url_for('main.serve_proxy_file', file_id=f.id)} for f in user_files]
|
|
return render_template('plater.html', w=w, h=h, hd=hd, presets=presets, last_quality=last_quality, models=models)
|
|
|
|
@main_bp.route('/file/<int:file_id>')
|
|
@login_required
|
|
def serve_file(file_id):
|
|
f = PrintFile.query.get_or_404(file_id)
|
|
if f.user_id != current_user.id and not current_user.is_admin:
|
|
abort(403)
|
|
path = os.path.join(current_app.config['UPLOAD_FOLDER'], f.filename)
|
|
return send_file(path)
|
|
|
|
@main_bp.route('/proxy/<int:file_id>')
|
|
@login_required
|
|
def serve_proxy_file(file_id):
|
|
f = PrintFile.query.get_or_404(file_id)
|
|
if f.user_id != current_user.id and not current_user.is_admin:
|
|
abort(403)
|
|
path = os.path.join(current_app.config['UPLOAD_FOLDER'], f.filename)
|
|
proxy_path = path + '.proxy.stl'
|
|
if not os.path.exists(proxy_path):
|
|
from stl_simplifier import simplify_stl
|
|
try:
|
|
simplify_stl(path, proxy_path, keep_ratio=0.1) # compress to 10%
|
|
except:
|
|
return send_file(path) # fallback to original if error
|
|
if os.path.exists(proxy_path):
|
|
return send_file(proxy_path)
|
|
return send_file(path)
|
|
|
|
@main_bp.route('/api/merge_and_slice', methods=['POST'])
|
|
@login_required
|
|
def merge_and_slice():
|
|
data = request.json
|
|
pieces = data.get('pieces', [])
|
|
quality = data.get('quality', 'base_global_standard.inst.cfg')
|
|
|
|
if not pieces:
|
|
return jsonify({'error': 'No pieces provided'}), 400
|
|
|
|
inputs = []
|
|
# Build a combined name
|
|
names = []
|
|
for p in pieces[:3]: # Cap names at 3 to avoid super long string
|
|
f = PrintFile.query.get(p['file_id'])
|
|
if f and (f.user_id == current_user.id or current_user.is_admin):
|
|
names.append(f.original_filename.replace('.stl', ''))
|
|
|
|
combined_name = ", ".join(names)
|
|
if len(pieces) > 3:
|
|
combined_name += "等合并切片"
|
|
else:
|
|
combined_name += "合并切片"
|
|
|
|
for p in pieces:
|
|
f = PrintFile.query.get(p['file_id'])
|
|
if f and (f.user_id == current_user.id or current_user.is_admin):
|
|
path = os.path.join(current_app.config['UPLOAD_FOLDER'], f.filename)
|
|
inputs.append((path, p['matrix']))
|
|
|
|
if not inputs:
|
|
return jsonify({'error': 'Invalid files'}), 400
|
|
|
|
timestamp = datetime.now().strftime('%Y%m%d%H%M%S')
|
|
unique_filename = f"{timestamp}_{uuid.uuid4().hex}.stl"
|
|
merged_filepath = os.path.join(current_app.config['UPLOAD_FOLDER'], unique_filename)
|
|
|
|
print_file = PrintFile(
|
|
filename=unique_filename,
|
|
original_filename=f"{combined_name}.stl",
|
|
file_type='stl',
|
|
user_id=current_user.id,
|
|
status='merging'
|
|
)
|
|
db.session.add(print_file)
|
|
db.session.commit()
|
|
|
|
from .tasks import merge_and_slice_task
|
|
merge_and_slice_task(print_file.id, inputs, merged_filepath, quality)
|
|
|
|
return jsonify({'success': True, 'message': 'Plater slice queued!'})
|
|
"""
|
|
|
|
# Only patch if not already present
|
|
if 'def plater()' not in content:
|
|
with open('app/routes.py', 'w', encoding='utf-8') as f:
|
|
# Prepend imports if needed
|
|
lines = content.split('\n')
|
|
# Insert mostly at the end
|
|
new_content = "\n".join(lines[:-1]) + functions + routes + "\n"
|
|
f.write(prefix + new_content)
|
|
print("Repatched successfully.")
|
|
else:
|
|
print("Already present.")
|