mirror of
https://github.com/RunLit/Bambu-Run.git
synced 2026-06-22 22:19:03 +01:00
docker deployment patch with verification and broken UI fixes (#1)
* bypass bambu cloud api opencb requirement * project root add to managepy * update instruction to do migration; mqtt login more verbose * migrations up to date model * use migrations from django migrate * print full token to copy paste * allow local network hosts * added side bar toggle * removed standalone css from dashboard css * added icon and fixed text trunction issue * fixed chart missing whitenoise and not rendering * aded favicon and fixed ui issues
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -687,27 +687,28 @@ class BambuPrinter:
|
||||
print("BambuLab Authentication")
|
||||
print("=" * 60)
|
||||
print(f"Authenticating as: {self.username}")
|
||||
print("This may require email verification (2FA)...")
|
||||
print()
|
||||
print(">>> ACTION MAY BE REQUIRED <<<")
|
||||
print("Bambu Lab will send a 6-digit verification code to your")
|
||||
print("registered email. Watch this terminal — if a prompt")
|
||||
print(f"appears below, enter the code and press Enter.")
|
||||
print(f"(You have {verification_code_timeout} seconds to respond.)")
|
||||
print("=" * 60)
|
||||
print()
|
||||
|
||||
auth = BambuAuthenticator()
|
||||
|
||||
try:
|
||||
if self._silent:
|
||||
with suppress_stdout():
|
||||
token = auth.get_or_create_token(
|
||||
username=self.username,
|
||||
password=self.password
|
||||
)
|
||||
else:
|
||||
token = auth.get_or_create_token(
|
||||
username=self.username,
|
||||
password=self.password
|
||||
)
|
||||
# Always show stdout during auth — suppress_stdout would hide
|
||||
# interactive prompts from the library (e.g. verification code input).
|
||||
token = auth.get_or_create_token(
|
||||
username=self.username,
|
||||
password=self.password
|
||||
)
|
||||
|
||||
self._token = token
|
||||
print("Authentication successful!")
|
||||
print(f"Token: {token[:20]}...{token[-10:]}")
|
||||
print(f"Token: {token}")
|
||||
print("=" * 60 + "\n")
|
||||
logger.info("BambuLab token obtained successfully")
|
||||
return token
|
||||
|
||||
@@ -5,6 +5,11 @@
|
||||
height: 300px;
|
||||
}
|
||||
|
||||
.no-data-message {
|
||||
font-size: 0.9rem;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Card styling */
|
||||
.infra-card-warning {
|
||||
background: linear-gradient(135deg, #ffc107 0%, #ffb300 100%);
|
||||
|
||||
@@ -4,10 +4,30 @@
|
||||
let nozzleTempChart, bedTempChart, printProgressChart, fanSpeedsChart;
|
||||
let wifiSignalChart, amsConditionsChart, layerProgressChart, filamentTimelineChart;
|
||||
|
||||
function showNoDataMessage(canvasId) {
|
||||
const canvas = document.getElementById(canvasId);
|
||||
if (!canvas) return;
|
||||
const container = canvas.closest('.chart-container');
|
||||
if (!container) return;
|
||||
canvas.style.display = 'none';
|
||||
const msg = document.createElement('div');
|
||||
msg.className = 'no-data-message d-flex align-items-center justify-content-center h-100 text-body-secondary';
|
||||
msg.textContent = 'No data available for this period';
|
||||
container.appendChild(msg);
|
||||
}
|
||||
|
||||
function initPrinterCharts(printerData, apiUrl) {
|
||||
// Apply filament card colors
|
||||
applyFilamentColors();
|
||||
|
||||
// If no data, show placeholder messages and exit early
|
||||
if (!printerData.timestamps || printerData.timestamps.length === 0) {
|
||||
['nozzleTempChart', 'bedTempChart', 'printProgressChart', 'fanSpeedsChart',
|
||||
'wifiSignalChart', 'amsConditionsChart', 'layerProgressChart', 'filamentTimelineChart'
|
||||
].forEach(showNoDataMessage);
|
||||
return;
|
||||
}
|
||||
|
||||
// Register the annotation plugin
|
||||
if (typeof Chart !== 'undefined' && typeof ChartAnnotation !== 'undefined') {
|
||||
Chart.register(ChartAnnotation);
|
||||
|
||||
1672
bambu_run/static/bambu_run/vendors/coreui-icons-free.svg
vendored
Normal file
1672
bambu_run/static/bambu_run/vendors/coreui-icons-free.svg
vendored
Normal file
File diff suppressed because it is too large
Load Diff
|
After Width: | Height: | Size: 410 KiB |
@@ -1,55 +1,101 @@
|
||||
{% load static %}
|
||||
<!DOCTYPE html>
|
||||
<html lang="en" data-coreui-theme="dark">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<!-- Apply saved theme immediately to prevent flash -->
|
||||
<script>
|
||||
(function(){
|
||||
var t = localStorage.getItem('bambu-run-theme') || 'dark';
|
||||
if (t === 'auto') t = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
||||
document.documentElement.setAttribute('data-coreui-theme', t);
|
||||
})();
|
||||
</script>
|
||||
<title>{% block title %}Bambu Run{% endblock %}</title>
|
||||
<!-- CoreUI 5.3 CSS CDN -->
|
||||
<link href="https://cdn.jsdelivr.net/npm/@coreui/coreui@5.3.0/dist/css/coreui.min.css" rel="stylesheet">
|
||||
<link href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/css/all.min.css" rel="stylesheet">
|
||||
<!-- Bootstrap Icons (for bi-vinyl filament icon) -->
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css">
|
||||
{% block extra_css %}{% endblock %}
|
||||
{% block extra_head %}{% endblock %}
|
||||
<style>
|
||||
.sidebar-brand { padding: 1rem; font-size: 1.25rem; font-weight: 700; }
|
||||
/* Sidebar brand sizing and padding */
|
||||
.sidebar-brand {
|
||||
padding: 1rem 1rem 1.25rem;
|
||||
font-size: 1.25rem;
|
||||
font-weight: 700;
|
||||
min-height: 56px;
|
||||
align-items: center;
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
}
|
||||
/* Hide brand text when sidebar is narrow */
|
||||
.sidebar-narrow-unfoldable:not(:hover) .sidebar-brand-text {
|
||||
display: none;
|
||||
}
|
||||
/* Gap between brand icon and text */
|
||||
.sidebar-brand img + .sidebar-brand-text {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
/* Sidebar collapse layout — standalone only */
|
||||
.wrapper { transition: margin-left 0.15s ease-out; }
|
||||
@media (min-width: 992px) {
|
||||
.sidebar ~ .wrapper { margin-left: 256px; }
|
||||
.sidebar.sidebar-narrow ~ .wrapper,
|
||||
.sidebar.sidebar-narrow-unfoldable ~ .wrapper { margin-left: 56px; }
|
||||
}
|
||||
@media (max-width: 991.98px) {
|
||||
.sidebar ~ .wrapper { margin-left: 0; }
|
||||
}
|
||||
/* Theme toggle icon visibility — driven by data-coreui-theme on <html> */
|
||||
[data-coreui-theme="dark"] .theme-icon-light { display: none; }
|
||||
[data-coreui-theme="light"] .theme-icon-dark { display: none; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="sidebar sidebar-dark sidebar-fixed" id="sidebar">
|
||||
<div class="sidebar-brand d-none d-md-flex">
|
||||
Bambu Run
|
||||
{% block sidebar_brand_icon %}{% endblock %}
|
||||
<span class="sidebar-brand-text">Bambu Run</span>
|
||||
</div>
|
||||
<ul class="sidebar-nav" data-coreui="navigation">
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'bambu_run:printer_dashboard' %}">
|
||||
<svg class="nav-icon"><use xlink:href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/sprites/free.svg#cil-print"></use></svg>
|
||||
<svg class="nav-icon"><use href="{% static 'bambu_run/vendors/coreui-icons-free.svg' %}#cil-expand-down"></use></svg>
|
||||
3D Printer
|
||||
</a>
|
||||
</li>
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'bambu_run:filament_list' %}">
|
||||
<svg class="nav-icon"><use xlink:href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/sprites/free.svg#cil-layers"></use></svg>
|
||||
<i class="nav-icon bi bi-vinyl"></i>
|
||||
Filament Inventory
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="sidebar-footer border-top d-flex">
|
||||
<button class="sidebar-toggler" type="button"></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="wrapper d-flex flex-column min-vh-100">
|
||||
<header class="header header-sticky p-0 mb-4">
|
||||
<div class="container-fluid px-4">
|
||||
<button class="header-toggler" type="button" onclick="document.getElementById('sidebar').classList.toggle('show')">
|
||||
<svg class="icon icon-lg"><use xlink:href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/sprites/free.svg#cil-menu"></use></svg>
|
||||
<button class="header-toggler d-lg-none" type="button"
|
||||
onclick="coreui.Sidebar.getInstance(document.querySelector('#sidebar')).toggle()">
|
||||
<svg class="icon icon-lg"><use href="{% static 'bambu_run/vendors/coreui-icons-free.svg' %}#cil-menu"></use></svg>
|
||||
</button>
|
||||
<ul class="header-nav ms-auto">
|
||||
{% block theme_toggle %}
|
||||
<li class="nav-item">
|
||||
<button class="nav-link" id="themeToggle" type="button">
|
||||
<svg class="icon icon-lg"><use xlink:href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/sprites/free.svg#cil-moon"></use></svg>
|
||||
<svg class="icon icon-lg theme-icon-dark"><use href="{% static 'bambu_run/vendors/coreui-icons-free.svg' %}#cil-moon"></use></svg>
|
||||
<svg class="icon icon-lg theme-icon-light"><use href="{% static 'bambu_run/vendors/coreui-icons-free.svg' %}#cil-sun"></use></svg>
|
||||
</button>
|
||||
</li>
|
||||
{% if user.is_authenticated %}
|
||||
<li class="nav-item">
|
||||
<a class="nav-link" href="{% url 'logout' %}">Logout</a>
|
||||
</li>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
{% block logout_nav %}{% endblock %}
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
@@ -62,18 +108,31 @@
|
||||
|
||||
<footer class="footer px-4">
|
||||
<div>Bambu Run</div>
|
||||
<div class="ms-auto">Powered by <a href="https://github.com/runnanli/Bambu-Run">Bambu Run</a></div>
|
||||
<div class="ms-auto">Powered by <a href="https://github.com/RunLit/Bambu-Run.git">Bambu Run</a></div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
<!-- CoreUI 5.3 JS CDN -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/@coreui/coreui@5.3.0/dist/js/coreui.bundle.min.js"></script>
|
||||
<script>
|
||||
// Theme toggle
|
||||
// Sidebar narrow-toggle with state persistence
|
||||
const sidebarToggler = document.querySelector('.sidebar-toggler');
|
||||
const sidebar = document.querySelector('#sidebar');
|
||||
if (sidebarToggler && sidebar) {
|
||||
if (localStorage.getItem('bambu-run-sidebar-narrow') === 'true') {
|
||||
sidebar.classList.add('sidebar-narrow-unfoldable');
|
||||
}
|
||||
sidebarToggler.addEventListener('click', (e) => {
|
||||
e.preventDefault(); e.stopPropagation();
|
||||
const isNarrow = sidebar.classList.contains('sidebar-narrow-unfoldable');
|
||||
sidebar.classList.toggle('sidebar-narrow-unfoldable', !isNarrow);
|
||||
localStorage.setItem('bambu-run-sidebar-narrow', String(!isNarrow));
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<script>
|
||||
// Simple 2-state theme toggle (standalone default)
|
||||
const themeToggle = document.getElementById('themeToggle');
|
||||
const savedTheme = localStorage.getItem('bambu-run-theme') || 'dark';
|
||||
document.documentElement.setAttribute('data-coreui-theme', savedTheme);
|
||||
|
||||
if (themeToggle) {
|
||||
themeToggle.addEventListener('click', function() {
|
||||
const current = document.documentElement.getAttribute('data-coreui-theme');
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
<h6 class="mb-0">Tray {{ filament.tray_id }}</h6>
|
||||
{% if filament.filament_pk %}
|
||||
<a href="{% url 'bambu_run:filament_detail' filament.filament_pk %}" class="text-decoration-none" title="View in inventory">
|
||||
<svg class="icon icon-sm text-body-secondary"><use xlink:href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/sprites/free.svg#cil-external-link"></use></svg>
|
||||
<svg class="icon icon-sm text-body-secondary"><use href="{% static 'bambu_run/vendors/coreui-icons-free.svg' %}#cil-external-link"></use></svg>
|
||||
</a>
|
||||
{% endif %}
|
||||
</div>
|
||||
@@ -235,11 +235,11 @@
|
||||
</div>
|
||||
<!-- Buttons -->
|
||||
<button type="button" class="btn btn-primary btn-sm" id="refreshPrinterCharts">
|
||||
<svg class="icon"><use xlink:href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/sprites/free.svg#cil-reload"></use></svg>
|
||||
<svg class="icon"><use href="{% static 'bambu_run/vendors/coreui-icons-free.svg' %}#cil-reload"></use></svg>
|
||||
Refresh
|
||||
</button>
|
||||
<button type="button" class="btn btn-secondary btn-sm" id="resetPrinterCharts">
|
||||
<svg class="icon"><use xlink:href="https://cdn.jsdelivr.net/npm/@coreui/icons@3.0.1/sprites/free.svg#cil-action-undo"></use></svg>
|
||||
<svg class="icon"><use href="{% static 'bambu_run/vendors/coreui-icons-free.svg' %}#cil-action-undo"></use></svg>
|
||||
Reset
|
||||
</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user