修复偏移问题,修复代理问题
This commit is contained in:
@@ -13,6 +13,7 @@ from app.utils.tasks import merge_and_slice_task, slice_stl_task, simplify_stl_t
|
||||
from app import i18n_dict
|
||||
# import trimesh.repair
|
||||
from app.utils.stl_simplifier import simplify_stl
|
||||
from app.routes.admin_routes import get_gcode_dir
|
||||
|
||||
|
||||
main_bp = Blueprint('main', __name__)
|
||||
@@ -21,6 +22,53 @@ main_bp = Blueprint('main', __name__)
|
||||
auth_bp = Blueprint('auth', __name__, url_prefix='/auth')
|
||||
admin_bp = Blueprint('admin', __name__, url_prefix='/admin')
|
||||
|
||||
|
||||
def get_quota_info(user, file_type):
|
||||
# Returns (quota_mb, current_size_bytes)
|
||||
if user.is_admin:
|
||||
quota_mb = 0.0
|
||||
else:
|
||||
conf = SystemConfig.query.filter_by(key=f"user_{user.id}_{file_type}_quota_mb").first()
|
||||
quota_mb = float(conf.value) if conf else 0.0
|
||||
|
||||
if quota_mb == 0.0:
|
||||
if user.is_guest:
|
||||
def_conf = SystemConfig.query.filter_by(key=f"default_guest_{file_type}_quota_mb").first()
|
||||
else:
|
||||
def_conf = SystemConfig.query.filter_by(key=f"default_user_{file_type}_quota_mb").first()
|
||||
quota_mb = float(def_conf.value) if def_conf else 0.0
|
||||
|
||||
user_files = PrintFile.query.filter_by(user_id=user.id).all()
|
||||
current_size = 0
|
||||
upload_dir = current_app.config.get('UPLOAD_FOLDER', 'uploads')
|
||||
gcode_dir = get_gcode_dir()
|
||||
|
||||
for pf in user_files:
|
||||
if file_type == 'stl' and not pf.original_filename.lower().endswith(('.gcode', '.gco', '.g')):
|
||||
path = os.path.join(upload_dir, pf.filename)
|
||||
if os.path.exists(path):
|
||||
current_size += os.path.getsize(path)
|
||||
elif file_type == 'gcode':
|
||||
g_filename = pf.filename.rsplit('.', 1)[0] + '.gcode'
|
||||
path = os.path.join(gcode_dir, g_filename)
|
||||
if os.path.exists(path):
|
||||
current_size += os.path.getsize(path)
|
||||
else:
|
||||
p2 = os.path.join(upload_dir, g_filename)
|
||||
if os.path.exists(p2): current_size += os.path.getsize(p2)
|
||||
|
||||
return quota_mb, current_size
|
||||
|
||||
def check_quota(user, file_type, size_bytes):
|
||||
if user.is_admin:
|
||||
return True
|
||||
quota_mb, current_size = get_quota_info(user, file_type)
|
||||
if quota_mb <= 0.0:
|
||||
return True
|
||||
if current_size + size_bytes > quota_mb * 1024 * 1024:
|
||||
return False
|
||||
return True
|
||||
|
||||
# Guest User Middleware
|
||||
@main_bp.before_app_request
|
||||
def assign_guest_cookie():
|
||||
@@ -48,8 +96,68 @@ def set_guest_cookie(response):
|
||||
# --- Main Routes ---
|
||||
|
||||
@main_bp.route('/')
|
||||
@login_required
|
||||
def index():
|
||||
return render_template('slice/index.html')
|
||||
user_files = PrintFile.query.filter((PrintFile.user_id == current_user.id) | (current_user.is_admin)).all() if current_user.is_admin else PrintFile.query.filter_by(user_id=current_user.id).all()
|
||||
|
||||
stl_count = 0
|
||||
stl_size = 0
|
||||
gcode_count = 0
|
||||
gcode_size = 0
|
||||
|
||||
upload_dir = current_app.config.get('UPLOAD_FOLDER', 'uploads')
|
||||
gcode_dir = get_gcode_dir()
|
||||
|
||||
for f in user_files:
|
||||
is_external_gcode = f.original_filename.lower().endswith(('.gcode', '.gco', '.g'))
|
||||
|
||||
if is_external_gcode:
|
||||
gcode_count += 1
|
||||
gcode_path = os.path.join(gcode_dir, f.filename.replace('.stl', '.gcode'))
|
||||
if os.path.exists(gcode_path):
|
||||
gcode_size += os.path.getsize(gcode_path)
|
||||
else:
|
||||
stl_count += 1
|
||||
stl_path = os.path.join(upload_dir, f.filename)
|
||||
if os.path.exists(stl_path):
|
||||
stl_size += os.path.getsize(stl_path)
|
||||
|
||||
if f.status == 'sliced':
|
||||
gcode_count += 1
|
||||
gcode_filename = f.filename.rsplit('.', 1)[0] + '.gcode'
|
||||
gcode_path = os.path.join(gcode_dir, gcode_filename)
|
||||
if os.path.exists(gcode_path):
|
||||
gcode_size += os.path.getsize(gcode_path)
|
||||
else:
|
||||
gcode_fallback = os.path.join(upload_dir, gcode_filename)
|
||||
if os.path.exists(gcode_fallback):
|
||||
gcode_size += os.path.getsize(gcode_fallback)
|
||||
|
||||
def format_size(size_bytes):
|
||||
if size_bytes < 1024:
|
||||
return f"{size_bytes} B"
|
||||
elif size_bytes < 1024 * 1024:
|
||||
return f"{size_bytes / 1024:.2f} KB"
|
||||
elif size_bytes < 1024 * 1024 * 1024:
|
||||
return f"{size_bytes / (1024 * 1024):.2f} MB"
|
||||
else:
|
||||
return f"{size_bytes / (1024 * 1024 * 1024):.2f} GB"
|
||||
|
||||
|
||||
stl_quota_mb, stl_used_bytes = get_quota_info(current_user, 'stl')
|
||||
gcode_quota_mb, gcode_used_bytes = get_quota_info(current_user, 'gcode')
|
||||
|
||||
return render_template('slice/index.html',
|
||||
stl_count=stl_count,
|
||||
stl_size_str=format_size(stl_size),
|
||||
gcode_count=gcode_count,
|
||||
gcode_size_str=format_size(gcode_size),
|
||||
stl_used_bytes=stl_used_bytes,
|
||||
stl_quota_mb=stl_quota_mb,
|
||||
gcode_used_bytes=gcode_used_bytes,
|
||||
gcode_quota_mb=gcode_quota_mb,
|
||||
format_size=format_size
|
||||
)
|
||||
|
||||
@main_bp.route('/set_language/<lang>')
|
||||
def set_language(lang):
|
||||
@@ -78,6 +186,15 @@ def files():
|
||||
if file.filename == '':
|
||||
continue
|
||||
if file and file.filename.lower().endswith('.stl'):
|
||||
file.seek(0, os.SEEK_END)
|
||||
size_bytes = file.tell()
|
||||
file.seek(0, os.SEEK_SET)
|
||||
if not check_quota(current_user, 'stl', size_bytes):
|
||||
if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
|
||||
return jsonify({'error': 'STL Storage Quota Exceeded'}), 400
|
||||
flash('STL Storage Quota Exceeded', 'danger')
|
||||
continue
|
||||
|
||||
original_filename = file.filename # Do not use secure_filename to keep Chinese characters
|
||||
ext = os.path.splitext(original_filename)[1].lower()
|
||||
if not ext:
|
||||
@@ -223,6 +340,9 @@ def get_quality_presets():
|
||||
@main_bp.route('/plater')
|
||||
@login_required
|
||||
def plater():
|
||||
quota_mb, current_size = get_quota_info(current_user, 'gcode')
|
||||
quota_exceeded = (quota_mb > 0 and current_size >= quota_mb * 1024 * 1024)
|
||||
|
||||
w, h, hd = get_bed_dimensions()
|
||||
presets = get_quality_presets()
|
||||
|
||||
@@ -237,7 +357,7 @@ def plater():
|
||||
|
||||
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, 'status': f.status, 'url': url_for('main.serve_proxy_file', file_id=f.id), 'transform_matrix': f.transform_matrix} for f in user_files]
|
||||
return render_template('slice/plater.html', w=w, h=h, hd=hd, presets=presets, last_quality=default_quality, models=models, offset_x=offset_x, offset_y=offset_y, default_infill=default_infill, default_support=default_support, default_support_pattern=default_support_pattern)
|
||||
return render_template('slice/plater.html', w=w, h=h, hd=hd, presets=presets, last_quality=default_quality, models=models, offset_x=offset_x, offset_y=offset_y, default_infill=default_infill, default_support=default_support, default_support_pattern=default_support_pattern, quota_exceeded=quota_exceeded)
|
||||
|
||||
@main_bp.route('/file/<int:file_id>')
|
||||
@login_required
|
||||
@@ -263,6 +383,9 @@ def serve_proxy_file(file_id):
|
||||
@main_bp.route('/api/merge_and_slice', methods=['POST'])
|
||||
@login_required
|
||||
def merge_and_slice():
|
||||
quota_mb, current_size = get_quota_info(current_user, 'gcode')
|
||||
if quota_mb > 0 and current_size >= quota_mb * 1024 * 1024:
|
||||
return jsonify({'success': False, 'error': 'GCode Storage Quota Exceeded. Please delete some files first.'})
|
||||
data = request.json
|
||||
pieces = data.get('pieces', [])
|
||||
quality = data.get('quality', 'base_global_standard.inst.cfg')
|
||||
|
||||
Reference in New Issue
Block a user