Initial spin-off of bambu-run from my private project separation

This commit is contained in:
RNL
2026-02-15 23:51:36 +11:00
parent 37c84fcd9f
commit 441db069c5
43 changed files with 7295 additions and 1 deletions

0
standalone/__init__.py Normal file
View File

21
standalone/manage.py Normal file
View File

@@ -0,0 +1,21 @@
#!/usr/bin/env python
"""Django's command-line utility for Bambu Run standalone deployment."""
import os
import sys
def main():
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "standalone.settings")
try:
from django.core.management import execute_from_command_line
except ImportError as exc:
raise ImportError(
"Couldn't import Django. Are you sure it's installed and "
"available on your PYTHONPATH environment variable? Did you "
"forget to activate a virtual environment?"
) from exc
execute_from_command_line(sys.argv)
if __name__ == "__main__":
main()

138
standalone/settings.py Normal file
View File

@@ -0,0 +1,138 @@
"""
Minimal Django settings for Bambu Run standalone deployment.
Reads configuration from environment variables or .env file.
"""
import os
from pathlib import Path
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = os.environ.get(
"DJANGO_SECRET_KEY",
"bambu-run-insecure-default-change-me-in-production",
)
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = os.environ.get("DEBUG", "True").lower() in ("true", "1", "yes")
ALLOWED_HOSTS = os.environ.get("ALLOWED_HOSTS", "localhost,127.0.0.1").split(",")
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"bambu_run",
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "standalone.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / "standalone" / "templates"],
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "standalone.wsgi.application"
# Database — SQLite for zero-setup deployment
DATA_DIR = Path(os.environ.get("DATA_DIR", BASE_DIR / "data"))
DATA_DIR.mkdir(parents=True, exist_ok=True)
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": DATA_DIR / "db.sqlite3",
}
}
# Password validation
AUTH_PASSWORD_VALIDATORS = [
{"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator"},
{"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator"},
{"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator"},
{"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator"},
]
# Internationalization
LANGUAGE_CODE = "en-us"
TIME_ZONE = os.environ.get("TIMEZONE", "UTC")
USE_I18N = True
USE_TZ = True
# Static files
STATIC_URL = "static/"
STATIC_ROOT = BASE_DIR / "staticfiles"
# Default primary key field type
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
# Login / Logout
LOGIN_URL = "/accounts/login/"
LOGIN_REDIRECT_URL = "/"
LOGOUT_REDIRECT_URL = "/accounts/login/"
# Bambu Run settings
BAMBU_RUN_TIMEZONE = os.environ.get("TIMEZONE", "UTC")
BAMBU_RUN_BASE_TEMPLATE = "bambu_run/base.html"
# Printer connection — read from environment
PRINTER_IP = os.environ.get("PRINTER_IP", "")
ACCESS_TOKEN = os.environ.get("ACCESS_TOKEN", "")
PRINTER_SERIAL = os.environ.get("PRINTER_SERIAL", "")
# Logging
LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"verbose": {
"format": "{asctime} {levelname} {name} {message}",
"style": "{",
},
},
"handlers": {
"console": {
"class": "logging.StreamHandler",
"formatter": "verbose",
},
},
"root": {
"handlers": ["console"],
"level": "INFO",
},
"loggers": {
"bambu_run": {
"handlers": ["console"],
"level": "DEBUG" if DEBUG else "INFO",
"propagate": False,
},
},
}

View File

@@ -0,0 +1,47 @@
<!DOCTYPE html>
<html lang="en" data-coreui-theme="dark">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Login - Bambu Run</title>
<link href="https://cdn.jsdelivr.net/npm/@coreui/coreui@5.3.0/dist/css/coreui.min.css" rel="stylesheet">
</head>
<body class="bg-body-tertiary min-vh-100 d-flex flex-row align-items-center">
<div class="container">
<div class="row justify-content-center">
<div class="col-lg-4">
<div class="card-group d-block d-md-flex row">
<div class="card p-4">
<div class="card-body">
<h1>Bambu Run</h1>
<p class="text-body-secondary">Sign in to your account</p>
{% if form.errors %}
<div class="alert alert-danger">
Invalid username or password.
</div>
{% endif %}
<form method="post">
{% csrf_token %}
<div class="input-group mb-3">
<span class="input-group-text">@</span>
<input type="text" name="username" class="form-control" placeholder="Username" autofocus>
</div>
<div class="input-group mb-4">
<span class="input-group-text">*</span>
<input type="password" name="password" class="form-control" placeholder="Password">
</div>
<div class="row">
<div class="col-6">
<button class="btn btn-primary px-4" type="submit">Login</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/@coreui/coreui@5.3.0/dist/js/coreui.bundle.min.js"></script>
</body>
</html>

13
standalone/urls.py Normal file
View File

@@ -0,0 +1,13 @@
"""URL configuration for Bambu Run standalone deployment."""
from django.contrib import admin
from django.contrib.auth import views as auth_views
from django.urls import include, path
from django.views.generic import RedirectView
urlpatterns = [
path("admin/", admin.site.urls),
path("accounts/login/", auth_views.LoginView.as_view(template_name="registration/login.html"), name="login"),
path("accounts/logout/", auth_views.LogoutView.as_view(), name="logout"),
path("", include("bambu_run.urls")),
]

9
standalone/wsgi.py Normal file
View File

@@ -0,0 +1,9 @@
"""WSGI config for Bambu Run standalone deployment."""
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "standalone.settings")
application = get_wsgi_application()