@@ -236,5 +236,6 @@
|
||||
"Internal infill": "Interne Füllung",
|
||||
"Bridge infill": "Brückefüllung",
|
||||
"Top solid infill": "Oberste solide Füllung",
|
||||
"Others": "Andere"
|
||||
"Others": "Andere",
|
||||
"Are you sure you want to clear the board?": "Sind Sie sicher, dass Sie das Brett leeren möchten?"
|
||||
}
|
||||
@@ -236,5 +236,6 @@
|
||||
"Internal infill": "Internal infill",
|
||||
"Bridge infill": "Bridge infill",
|
||||
"Top solid infill": "Top solid infill",
|
||||
"Others": "Others"
|
||||
"Others": "Others",
|
||||
"Are you sure you want to clear the board?": "Are you sure you want to clear the board?"
|
||||
}
|
||||
@@ -236,5 +236,6 @@
|
||||
"Internal infill": "内部填充",
|
||||
"Bridge infill": "桥接填充",
|
||||
"Top solid infill": "顶部实体填充",
|
||||
"Others": "其他"
|
||||
"Others": "其他",
|
||||
"Are you sure you want to clear the board?": "您确定要清空构建板吗?"
|
||||
}
|
||||
@@ -28,9 +28,85 @@ def login():
|
||||
username = request.form.get('username')
|
||||
password = request.form.get('password')
|
||||
user = User.query.filter_by(username=username, is_guest=False).first()
|
||||
|
||||
remember = bool(request.form.get('remember'))
|
||||
merge_data = bool(request.form.get('merge_data'))
|
||||
|
||||
if user and check_password_hash(user.password_hash, password):
|
||||
login_user(user)
|
||||
return redirect(url_for('main.index'))
|
||||
login_user(user, remember=remember)
|
||||
|
||||
if merge_data:
|
||||
guest_id = request.cookies.get('guest_id')
|
||||
if guest_id:
|
||||
guest_user = User.query.filter_by(guest_cookie_id=guest_id, is_guest=True).first()
|
||||
if guest_user:
|
||||
from app.routes.main_routes import get_quota_info
|
||||
guest_files = PrintFile.query.filter_by(user_id=guest_user.id).all()
|
||||
|
||||
stl_quota, stl_used = get_quota_info(user, 'stl')
|
||||
gcode_quota, gcode_used = get_quota_info(user, 'gcode')
|
||||
|
||||
stl_quota_bytes = stl_quota * 1024 * 1024 if stl_quota > 0 else float('inf')
|
||||
gcode_quota_bytes = gcode_quota * 1024 * 1024 if gcode_quota > 0 else float('inf')
|
||||
|
||||
from app.routes.admin_routes import get_gcode_dir
|
||||
upload_dir = current_app.config.get('UPLOAD_FOLDER', 'uploads')
|
||||
gcode_dir = get_gcode_dir()
|
||||
|
||||
for pf in guest_files:
|
||||
file_size = 0
|
||||
file_type = 'stl'
|
||||
is_external_gcode = pf.original_filename.lower().endswith(('.gcode', '.gco', '.g'))
|
||||
if is_external_gcode or pf.status == 'sliced':
|
||||
file_type = 'gcode'
|
||||
g_filename = pf.filename.rsplit('.', 1)[0] + '.gcode'
|
||||
path = os.path.join(gcode_dir, g_filename)
|
||||
if os.path.exists(path):
|
||||
file_size = os.path.getsize(path)
|
||||
else:
|
||||
p2 = os.path.join(upload_dir, g_filename)
|
||||
if os.path.exists(p2): file_size = os.path.getsize(p2)
|
||||
else:
|
||||
path = os.path.join(upload_dir, pf.filename)
|
||||
if os.path.exists(path):
|
||||
file_size = os.path.getsize(path)
|
||||
|
||||
# Check quota
|
||||
can_merge = True
|
||||
if not user.is_admin:
|
||||
if file_type == 'stl' and (stl_used + file_size > stl_quota_bytes):
|
||||
can_merge = False
|
||||
elif file_type == 'gcode' and (gcode_used + file_size > gcode_quota_bytes):
|
||||
can_merge = False
|
||||
|
||||
if can_merge:
|
||||
pf.user_id = user.id
|
||||
if file_type == 'stl': stl_used += file_size
|
||||
else: gcode_used += file_size
|
||||
else:
|
||||
# delete from disk to prevent orphans
|
||||
stl_path = os.path.join(upload_dir, pf.filename)
|
||||
proxy_path = stl_path + '.proxy.stl'
|
||||
gcode_filename = pf.filename.rsplit('.', 1)[0] + '.gcode'
|
||||
gp = os.path.join(gcode_dir, gcode_filename)
|
||||
fp = os.path.join(upload_dir, gcode_filename)
|
||||
if os.path.exists(stl_path): os.remove(stl_path)
|
||||
if os.path.exists(proxy_path): os.remove(proxy_path)
|
||||
if os.path.exists(gp): os.remove(gp)
|
||||
if os.path.exists(fp): os.remove(fp)
|
||||
db.session.delete(pf)
|
||||
|
||||
# Save changes to files first so SQLAlchemy doesn't try to nullify related keys
|
||||
db.session.commit()
|
||||
|
||||
# Delete guest user after merge
|
||||
db.session.delete(guest_user)
|
||||
db.session.commit()
|
||||
|
||||
response = make_response(redirect(url_for('main.index')))
|
||||
if merge_data:
|
||||
response.delete_cookie('guest_id')
|
||||
return response
|
||||
flash('Invalid username or password', 'danger')
|
||||
return render_template('auth/login.html')
|
||||
|
||||
|
||||
@@ -5,19 +5,27 @@
|
||||
<div class="col-md-6 mt-5">
|
||||
<div class="card shadow-sm">
|
||||
<div class="card-header bg-primary text-white">
|
||||
<h4 class="mb-0">Login</h4>
|
||||
<h4 class="mb-0">{{ _('Login') }}</h4>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<form method="POST" action="{{ url_for('auth.login') }}">
|
||||
<div class="mb-3">
|
||||
<label for="username" class="form-label">Username</label>
|
||||
<label for="username" class="form-label">{{ _('Username') }}</label>
|
||||
<input type="text" class="form-control" name="username" id="username" required>
|
||||
</div>
|
||||
<div class="mb-3">
|
||||
<label for="password" class="form-label">Password</label>
|
||||
<label for="password" class="form-label">{{ _('Password') }}</label>
|
||||
<input type="password" class="form-control" name="password" id="password" required>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100">Login</button>
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" class="form-check-input" name="remember" id="remember">
|
||||
<label class="form-check-label" for="remember">{{ _('Remember Me') }}</label>
|
||||
</div>
|
||||
<div class="mb-3 form-check">
|
||||
<input type="checkbox" class="form-check-input" name="merge_data" id="merge_data" checked>
|
||||
<label class="form-check-label" for="merge_data">{{ _('Merge Guest Data') }}</label>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary w-100">{{ _('Login') }}</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -131,7 +131,7 @@
|
||||
</div> <!-- End of accordion wrapper -->
|
||||
|
||||
<div class="mt-auto pt-3 border-top d-flex flex-column gap-2 mb-1">
|
||||
<button class="btn btn-outline-danger w-100" onclick="clearPlate()"><i class="bi bi-trash me-2"></i>{{ _('Clear Board') }}</button>
|
||||
<button class="btn btn-outline-danger w-100" onclick="customConfirm('{{ _('Are you sure you want to clear the board?') }}', clearPlate)"><i class="bi bi-trash me-2"></i>{{ _('Clear Board') }}</button>
|
||||
<button class="btn btn-primary w-100 py-2 fs-5 shadow-sm" onclick="mergeAndSlice()" id="btn-merge"><i class="bi bi-gear-fill me-2" id="merge-icon"></i><span id="merge-text">{{ _('Merge & Slice') }}</span></button>
|
||||
</div>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user