ophix-admin-settings 2026.10.4.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ophix_admin_settings-2026.10.4.1/PKG-INFO +72 -0
- ophix_admin_settings-2026.10.4.1/README.md +48 -0
- ophix_admin_settings-2026.10.4.1/pyproject.toml +53 -0
- ophix_admin_settings-2026.10.4.1/setup.cfg +4 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/OPHIX_RELEASE_NOTES.md +37 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/__init__.py +4 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/_version.py +2 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/admin.py +101 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/apps.py +25 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/context_processors.py +3 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/deploy_templates/env.fragment.j2 +2 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/docs/sections.yaml +3 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/docs/server-settings.md +80 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/management/__init__.py +0 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/management/commands/__init__.py +0 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/management/commands/export_settings.py +121 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/management/commands/import_settings.py +160 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/migrations/0001_initial.py +32 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/migrations/0002_serversettings_env_colors.py +72 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/migrations/0003_remove_env_visible_in_favicon.py +16 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/migrations/0004_serversettings_env_name_remove_help_text.py +25 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/migrations/0005_serversettings_message_autohide.py +29 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/migrations/0006_phase_e_notification_rename.py +30 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/migrations/__init__.py +0 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/models.py +144 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/settings.py +7 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/templates/admin/ophix_admin_settings/serversettings/change_form.html +105 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/validators.py +82 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings.egg-info/PKG-INFO +72 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings.egg-info/SOURCES.txt +32 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings.egg-info/dependency_links.txt +1 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings.egg-info/entry_points.txt +2 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings.egg-info/requires.txt +2 -0
- ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings.egg-info/top_level.txt +1 -0
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: ophix-admin-settings
|
|
3
|
+
Version: 2026.10.4.1
|
|
4
|
+
Summary: Instance settings for Ophix Project Servers - server identity, environment, and language
|
|
5
|
+
Author: Ophix Project
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://ophix.io
|
|
8
|
+
Keywords: django,ophix,admin,settings
|
|
9
|
+
Classifier: Development Status :: 4 - Beta
|
|
10
|
+
Classifier: Environment :: Web Environment
|
|
11
|
+
Classifier: Framework :: Django
|
|
12
|
+
Classifier: Intended Audience :: System Administrators
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
20
|
+
Requires-Python: >=3.10
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
Requires-Dist: django-colorfield
|
|
23
|
+
Requires-Dist: ophix-server-base>=2026.06.08.01
|
|
24
|
+
|
|
25
|
+
# ophix-admin-settings
|
|
26
|
+
|
|
27
|
+
**Know which server you're looking at, every time** — instance identity and environment labelling for every [Ophix](https://ophix.io) server.
|
|
28
|
+
|
|
29
|
+
Running the same admin UI across a dozen servers makes it easy to lose track of which one is actually in front of you — and that's exactly the moment someone edits production thinking it's staging. `ophix-admin-settings` gives every server its own title and a visible environment badge (Production, Staging, Dev, or whatever you call it), right in the header and favicon, so there's never any doubt.
|
|
30
|
+
|
|
31
|
+
This package is automatically included in every Ophix server, no need to separately install it.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## What it does
|
|
36
|
+
|
|
37
|
+
Provides a singleton **Server Settings** admin page containing settings that are instance-specific rather than theme-specific. These settings survive theme changes — switching from one theme to another does not alter the server's identity or environment label.
|
|
38
|
+
|
|
39
|
+
| Setting | Description |
|
|
40
|
+
| --- | --- |
|
|
41
|
+
| **Title** | Displayed in the browser tab and admin header (e.g. `TaskServer`, `CredServer`) |
|
|
42
|
+
| **Title visible** | Toggle title display in the admin header |
|
|
43
|
+
| **Environment name** | Short label shown in the header and favicon (e.g. `Production`, `Staging`, `Dev`) |
|
|
44
|
+
| **Env visible in header** | Show or hide the environment badge in the page header |
|
|
45
|
+
| **Env visible in favicon** | Show or hide the environment marker on the favicon |
|
|
46
|
+
| **Language chooser** | Active, control style (default/minimal), and display format (code/name) |
|
|
47
|
+
|
|
48
|
+
---
|
|
49
|
+
|
|
50
|
+
## Installation
|
|
51
|
+
|
|
52
|
+
Installed automatically with `ophix-admin-interface`. To install explicitly:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
pip install ophix-admin-settings
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Run migrations after installation:
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
ophix-manage migrate
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
On first `migrate`, the **title** field is pre-populated from the `SERVER_NAME` setting in `.env` if it is blank.
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## Docs import
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
ophix-manage update_docs --include-app-docs ophix.core,ophix_admin_settings,ophix_docs
|
|
72
|
+
```
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# ophix-admin-settings
|
|
2
|
+
|
|
3
|
+
**Know which server you're looking at, every time** — instance identity and environment labelling for every [Ophix](https://ophix.io) server.
|
|
4
|
+
|
|
5
|
+
Running the same admin UI across a dozen servers makes it easy to lose track of which one is actually in front of you — and that's exactly the moment someone edits production thinking it's staging. `ophix-admin-settings` gives every server its own title and a visible environment badge (Production, Staging, Dev, or whatever you call it), right in the header and favicon, so there's never any doubt.
|
|
6
|
+
|
|
7
|
+
This package is automatically included in every Ophix server, no need to separately install it.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## What it does
|
|
12
|
+
|
|
13
|
+
Provides a singleton **Server Settings** admin page containing settings that are instance-specific rather than theme-specific. These settings survive theme changes — switching from one theme to another does not alter the server's identity or environment label.
|
|
14
|
+
|
|
15
|
+
| Setting | Description |
|
|
16
|
+
| --- | --- |
|
|
17
|
+
| **Title** | Displayed in the browser tab and admin header (e.g. `TaskServer`, `CredServer`) |
|
|
18
|
+
| **Title visible** | Toggle title display in the admin header |
|
|
19
|
+
| **Environment name** | Short label shown in the header and favicon (e.g. `Production`, `Staging`, `Dev`) |
|
|
20
|
+
| **Env visible in header** | Show or hide the environment badge in the page header |
|
|
21
|
+
| **Env visible in favicon** | Show or hide the environment marker on the favicon |
|
|
22
|
+
| **Language chooser** | Active, control style (default/minimal), and display format (code/name) |
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
Installed automatically with `ophix-admin-interface`. To install explicitly:
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
pip install ophix-admin-settings
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Run migrations after installation:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
ophix-manage migrate
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
On first `migrate`, the **title** field is pre-populated from the `SERVER_NAME` setting in `.env` if it is blank.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## Docs import
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
ophix-manage update_docs --include-app-docs ophix.core,ophix_admin_settings,ophix_docs
|
|
48
|
+
```
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "ophix-admin-settings"
|
|
7
|
+
version = "2026.10.04.01"
|
|
8
|
+
description = "Instance settings for Ophix Project Servers - server identity, environment, and language"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "MIT"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "Ophix Project" }
|
|
14
|
+
]
|
|
15
|
+
keywords = ["django", "ophix", "admin", "settings"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Environment :: Web Environment",
|
|
19
|
+
"Framework :: Django",
|
|
20
|
+
"Intended Audience :: System Administrators",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
"Programming Language :: Python :: 3",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: Python :: 3.13",
|
|
27
|
+
"Programming Language :: Python :: 3.14",
|
|
28
|
+
]
|
|
29
|
+
dependencies = [
|
|
30
|
+
"django-colorfield",
|
|
31
|
+
"ophix-server-base>=2026.06.08.01",
|
|
32
|
+
]
|
|
33
|
+
|
|
34
|
+
[project.urls]
|
|
35
|
+
Homepage = "https://ophix.io"
|
|
36
|
+
|
|
37
|
+
[project.entry-points."ophix.plugins"]
|
|
38
|
+
ophix_admin_settings = "ophix_admin_settings"
|
|
39
|
+
|
|
40
|
+
[tool.setuptools]
|
|
41
|
+
package-dir = { "" = "src" }
|
|
42
|
+
|
|
43
|
+
[tool.setuptools.packages.find]
|
|
44
|
+
where = ["src"]
|
|
45
|
+
|
|
46
|
+
[tool.setuptools.package-data]
|
|
47
|
+
"ophix_admin_settings" = [
|
|
48
|
+
"OPHIX_RELEASE_NOTES.md",
|
|
49
|
+
"deploy_templates/**/*",
|
|
50
|
+
"docs/**/*",
|
|
51
|
+
"static/**/*",
|
|
52
|
+
"templates/**/*",
|
|
53
|
+
]
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# Ophix Admin Settings Release Notes
|
|
2
|
+
|
|
3
|
+
## 2026.10.04.01
|
|
4
|
+
|
|
5
|
+
- Reworked `README.md`'s opening with a hook-first pitch (instance identity and environment
|
|
6
|
+
labelling — knowing which server you're looking at before you edit it), as part of the
|
|
7
|
+
16-package taskserver-release-wave README overhaul.
|
|
8
|
+
|
|
9
|
+
## 2026.09.26.01
|
|
10
|
+
|
|
11
|
+
- Verified real compatibility under Python 3.14 (not just added the classifier) as part of the taskserver-release-wave compatibility sweep, and added `Programming Language :: Python :: 3.14` to the package classifiers.
|
|
12
|
+
|
|
13
|
+
## 2026.06.11.01
|
|
14
|
+
|
|
15
|
+
- Added `message_autohide_enabled` and `message_autohide_delay` fields to `ServerSettings`.
|
|
16
|
+
When enabled, success and info message banners are automatically dismissed after the
|
|
17
|
+
configured delay (default 4000 ms). Errors and warnings are never auto-hidden.
|
|
18
|
+
Exposed in the new "Notifications" section of the Server Settings admin page.
|
|
19
|
+
|
|
20
|
+
## 2026.06.09.02
|
|
21
|
+
|
|
22
|
+
- Added `export_settings` management command — exports the `ServerSettings` singleton
|
|
23
|
+
to a JSON file for backup or server migration.
|
|
24
|
+
- Added `import_settings` management command — imports from an `export_settings` file;
|
|
25
|
+
applies only fields present in the file, reports per-field changes, supports `--dry-run`.
|
|
26
|
+
- Updated server-settings docs: removed stale "Visible in favicon" row, updated env badge
|
|
27
|
+
colour description, added Backup and Migration section.
|
|
28
|
+
|
|
29
|
+
## 2026.05.31.01
|
|
30
|
+
|
|
31
|
+
- Initial release. Provides the `ServerSettings` singleton model for instance-specific
|
|
32
|
+
configuration: server title, environment label, and language chooser settings.
|
|
33
|
+
- Settings survive theme changes and are independent of the active theme.
|
|
34
|
+
- Title is pre-populated from `SERVER_NAME` in `.env` on first `migrate` if blank.
|
|
35
|
+
- Context processor `ophix_admin_settings.context_processors.settings_context` injects
|
|
36
|
+
`server_settings` into every admin template context via the `CONTEXT_PROCESSORS_APPEND`
|
|
37
|
+
plugin mechanism (requires `ophix-server-base>=2026.05.31.01`).
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from django.conf import settings
|
|
2
|
+
from django.contrib import admin, messages
|
|
3
|
+
from django.http import HttpResponseRedirect
|
|
4
|
+
from django.urls import reverse
|
|
5
|
+
from django.utils.translation import gettext_lazy as _
|
|
6
|
+
|
|
7
|
+
from .models import ServerSettings
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@admin.register(ServerSettings)
|
|
11
|
+
class ServerSettingsAdmin(admin.ModelAdmin):
|
|
12
|
+
|
|
13
|
+
def response_change(self, request, obj):
|
|
14
|
+
if "_save" in request.POST:
|
|
15
|
+
self.message_user(request, _("Server Settings saved successfully."), messages.SUCCESS)
|
|
16
|
+
return HttpResponseRedirect(reverse("admin:index"))
|
|
17
|
+
if "_continue" in request.POST:
|
|
18
|
+
self.message_user(request, _("Server Settings saved successfully."), messages.SUCCESS)
|
|
19
|
+
return HttpResponseRedirect(request.path)
|
|
20
|
+
return super().response_change(request, obj)
|
|
21
|
+
fieldsets = (
|
|
22
|
+
(
|
|
23
|
+
_("Server Identity"),
|
|
24
|
+
{
|
|
25
|
+
"classes": ("wide",),
|
|
26
|
+
"fields": ("title", "title_visible"),
|
|
27
|
+
},
|
|
28
|
+
),
|
|
29
|
+
(
|
|
30
|
+
_("Environment"),
|
|
31
|
+
{
|
|
32
|
+
"classes": ("wide",),
|
|
33
|
+
"fields": (
|
|
34
|
+
"env_name",
|
|
35
|
+
"env_visible_in_header",
|
|
36
|
+
("env_color", "env_color_dark_use", "env_color_dark"),
|
|
37
|
+
("env_text_color", "env_text_color_dark_use", "env_text_color_dark"),
|
|
38
|
+
),
|
|
39
|
+
"description": _(
|
|
40
|
+
"Small badge displayed in the header to identify the deployment environment "
|
|
41
|
+
"(e.g. PROD, DEV, TEST)."
|
|
42
|
+
),
|
|
43
|
+
},
|
|
44
|
+
),
|
|
45
|
+
(
|
|
46
|
+
_("Notifications"),
|
|
47
|
+
{
|
|
48
|
+
"classes": ("wide",),
|
|
49
|
+
"fields": ("message_autohide_enabled", "message_autohide_delay"),
|
|
50
|
+
"description": _(
|
|
51
|
+
"Configure automatic dismissal of system notifications. "
|
|
52
|
+
"Only success and info notifications are auto-dismissed; errors and warnings remain until page reload or user dismissal."
|
|
53
|
+
),
|
|
54
|
+
},
|
|
55
|
+
),
|
|
56
|
+
(
|
|
57
|
+
_("Language Chooser"),
|
|
58
|
+
{
|
|
59
|
+
"classes": ("wide",),
|
|
60
|
+
"fields": (
|
|
61
|
+
"language_chooser_active",
|
|
62
|
+
"language_chooser_control",
|
|
63
|
+
"language_chooser_display",
|
|
64
|
+
),
|
|
65
|
+
},
|
|
66
|
+
),
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
save_on_top = True
|
|
70
|
+
|
|
71
|
+
def change_view(self, request, object_id, form_url="", extra_context=None):
|
|
72
|
+
extra_context = extra_context or {}
|
|
73
|
+
from django.conf import settings as django_settings
|
|
74
|
+
if getattr(django_settings, "SHOW_THEME_MODEL", True):
|
|
75
|
+
try:
|
|
76
|
+
from admin_interface.models import Theme
|
|
77
|
+
extra_context["active_theme"] = Theme.objects.get_active()
|
|
78
|
+
except Exception:
|
|
79
|
+
extra_context["active_theme"] = None
|
|
80
|
+
else:
|
|
81
|
+
extra_context["active_theme"] = None
|
|
82
|
+
return super().change_view(request, object_id, form_url, extra_context)
|
|
83
|
+
|
|
84
|
+
def has_add_permission(self, request):
|
|
85
|
+
return False
|
|
86
|
+
|
|
87
|
+
def has_delete_permission(self, request, obj=None):
|
|
88
|
+
return False
|
|
89
|
+
|
|
90
|
+
def changelist_view(self, request, extra_context=None):
|
|
91
|
+
obj = ServerSettings.load()
|
|
92
|
+
return HttpResponseRedirect(
|
|
93
|
+
reverse("admin:ophix_admin_settings_serversettings_change", args=[obj.pk])
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
if not getattr(settings, "SHOW_SETTINGS_MODEL", False):
|
|
98
|
+
try:
|
|
99
|
+
admin.site.unregister(ServerSettings)
|
|
100
|
+
except admin.sites.NotRegistered:
|
|
101
|
+
pass
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
from django.apps import AppConfig
|
|
2
|
+
from django.utils.translation import gettext_lazy as _
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class OphixAdminSettingsConfig(AppConfig):
|
|
6
|
+
name = "ophix_admin_settings"
|
|
7
|
+
verbose_name = _("Settings")
|
|
8
|
+
admin_order = 810
|
|
9
|
+
default_auto_field = "django.db.models.AutoField"
|
|
10
|
+
|
|
11
|
+
def ready(self):
|
|
12
|
+
from django.db.models.signals import post_migrate
|
|
13
|
+
post_migrate.connect(_init_server_settings, sender=self)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def _init_server_settings(sender, **kwargs):
|
|
17
|
+
from django.apps import apps
|
|
18
|
+
from django.conf import settings
|
|
19
|
+
|
|
20
|
+
ServerSettings = apps.get_model("ophix_admin_settings", "ServerSettings")
|
|
21
|
+
obj = ServerSettings.load()
|
|
22
|
+
if not obj.title:
|
|
23
|
+
server_name = getattr(settings, "SERVER_NAME", "").strip()
|
|
24
|
+
obj.title = ("Ophix " + server_name).strip() if server_name else "Ophix"
|
|
25
|
+
obj.save(update_fields=["title"])
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Server Settings
|
|
3
|
+
slug: server-settings
|
|
4
|
+
order: 520
|
|
5
|
+
section: Extensions
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Server Settings
|
|
9
|
+
|
|
10
|
+
**Server Settings** holds instance-specific configuration — values that identify this particular server and should survive a theme change. Switching from one theme to another does not alter any setting here.
|
|
11
|
+
|
|
12
|
+
Access it via **Settings** in the admin sidebar.
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Server Identity
|
|
17
|
+
|
|
18
|
+
| Setting | Description |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| **Title** | Displayed first in the browser tab (`TaskServer \| Page Name`) and in the admin header. Pre-populated from `SERVER_NAME` in `.env` on first install if blank. |
|
|
21
|
+
| **Title visible** | Whether the title text appears in the admin header alongside the logo. |
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Environment
|
|
26
|
+
|
|
27
|
+
A short label that identifies the deployment environment. Useful when multiple instances of the same domain are running (e.g. production, staging, and dev).
|
|
28
|
+
|
|
29
|
+
| Setting | Description |
|
|
30
|
+
| --- | --- |
|
|
31
|
+
| **Environment name** | The label text, e.g. `Production`, `Staging`, `Dev`. |
|
|
32
|
+
| **Visible in header** | Show or hide the environment badge in the page header. |
|
|
33
|
+
| **Badge color** | Background colour of the environment badge (light and optional dark variant). |
|
|
34
|
+
| **Badge text color** | Text colour of the environment badge (light and optional dark variant). |
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Language Chooser
|
|
39
|
+
|
|
40
|
+
Controls whether operators can switch the admin UI language from the page header.
|
|
41
|
+
|
|
42
|
+
| Setting | Description |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| **Active** | Show or hide the language chooser in the header. |
|
|
45
|
+
| **Control** | Dropdown style: Default Select or Minimal Select. |
|
|
46
|
+
| **Display** | Show language as its two-letter code (e.g. `EN`) or full name (e.g. `English`). |
|
|
47
|
+
|
|
48
|
+
The language chooser only appears when `USE_I18N = True`, at least two languages are configured in `LANGUAGES`, and `LocaleMiddleware` is active.
|
|
49
|
+
|
|
50
|
+
---
|
|
51
|
+
|
|
52
|
+
## Backup and Migration
|
|
53
|
+
|
|
54
|
+
`export_settings` and `import_settings` let you preserve and restore the ServerSettings singleton — useful when migrating to a new server or cloning a staging environment.
|
|
55
|
+
|
|
56
|
+
**Export:**
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
ophix-manage export_settings --output-file settings.json
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
**Preview current values without writing:**
|
|
63
|
+
|
|
64
|
+
```bash
|
|
65
|
+
ophix-manage export_settings --output-file settings.json --dry-run
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**Import (applies all fields from the file):**
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
ophix-manage import_settings --input-file settings.json
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Preview what would change:**
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
ophix-manage import_settings --input-file settings.json --dry-run
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
Import is safe to re-run — fields that already match the current values are reported as unchanged. Fields present in the file but absent from the model are ignored with a warning; fields absent from the file are left at their current values.
|
|
File without changes
|
|
File without changes
|
ophix_admin_settings-2026.10.4.1/src/ophix_admin_settings/management/commands/export_settings.py
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""
|
|
2
|
+
ophix-manage export_settings
|
|
3
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
4
|
+
Export the ServerSettings singleton to a JSON file for backup or server migration.
|
|
5
|
+
|
|
6
|
+
No passphrase option is provided: ServerSettings contains no sensitive data
|
|
7
|
+
(title, environment badge, language chooser). Protect the file with filesystem
|
|
8
|
+
permissions as you would any configuration file.
|
|
9
|
+
|
|
10
|
+
Examples
|
|
11
|
+
--------
|
|
12
|
+
Export settings:
|
|
13
|
+
ophix-manage export_settings --output-file settings.json
|
|
14
|
+
|
|
15
|
+
Preview (shows current values without writing):
|
|
16
|
+
ophix-manage export_settings --output-file settings.json --dry-run
|
|
17
|
+
"""
|
|
18
|
+
|
|
19
|
+
import json
|
|
20
|
+
from pathlib import Path
|
|
21
|
+
|
|
22
|
+
from django.core.management.base import BaseCommand, CommandError
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _build_meta(command: str) -> dict:
|
|
26
|
+
import datetime
|
|
27
|
+
import os
|
|
28
|
+
import socket
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
import pwd
|
|
32
|
+
run_by = pwd.getpwuid(os.getuid()).pw_name
|
|
33
|
+
except Exception:
|
|
34
|
+
run_by = os.environ.get("USER") or os.environ.get("LOGNAME")
|
|
35
|
+
|
|
36
|
+
from django.conf import settings
|
|
37
|
+
ssh_raw = os.environ.get("SSH_CLIENT", "")
|
|
38
|
+
return {
|
|
39
|
+
"created_at": datetime.datetime.now(datetime.timezone.utc).isoformat(),
|
|
40
|
+
"server_name": getattr(settings, "SERVER_NAME", None),
|
|
41
|
+
"server_version": getattr(settings, "SERVER_VERSION", None),
|
|
42
|
+
"hostname": socket.gethostname(),
|
|
43
|
+
"command": command,
|
|
44
|
+
"run_by": run_by,
|
|
45
|
+
"login_user": os.environ.get("SUDO_USER") or None,
|
|
46
|
+
"ssh_origin": ssh_raw.split()[0] if ssh_raw else None,
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def _serialize(obj) -> dict:
|
|
51
|
+
return {
|
|
52
|
+
"title": obj.title,
|
|
53
|
+
"title_visible": obj.title_visible,
|
|
54
|
+
"env_name": obj.env_name,
|
|
55
|
+
"env_visible_in_header": obj.env_visible_in_header,
|
|
56
|
+
"env_color": obj.env_color,
|
|
57
|
+
"env_color_dark_use": obj.env_color_dark_use,
|
|
58
|
+
"env_color_dark": obj.env_color_dark,
|
|
59
|
+
"env_text_color": obj.env_text_color,
|
|
60
|
+
"env_text_color_dark_use": obj.env_text_color_dark_use,
|
|
61
|
+
"env_text_color_dark": obj.env_text_color_dark,
|
|
62
|
+
"language_chooser_active": obj.language_chooser_active,
|
|
63
|
+
"language_chooser_control": obj.language_chooser_control,
|
|
64
|
+
"language_chooser_display": obj.language_chooser_display,
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class Command(BaseCommand):
|
|
69
|
+
help = "Export the ServerSettings singleton to a JSON file for backup or server migration."
|
|
70
|
+
|
|
71
|
+
def add_arguments(self, parser):
|
|
72
|
+
parser.add_argument(
|
|
73
|
+
"--output-file",
|
|
74
|
+
required=True,
|
|
75
|
+
metavar="FILE",
|
|
76
|
+
help="Destination file path.",
|
|
77
|
+
)
|
|
78
|
+
parser.add_argument(
|
|
79
|
+
"--dry-run",
|
|
80
|
+
action="store_true",
|
|
81
|
+
help="Print the values that would be exported without writing the file.",
|
|
82
|
+
)
|
|
83
|
+
parser.add_argument(
|
|
84
|
+
"--quiet",
|
|
85
|
+
action="store_true",
|
|
86
|
+
help="Suppress all output.",
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
def handle(self, *args, **options):
|
|
90
|
+
from ophix_admin_settings.models import ServerSettings
|
|
91
|
+
|
|
92
|
+
output_path = Path(options["output_file"])
|
|
93
|
+
dry_run = options["dry_run"]
|
|
94
|
+
quiet = options["quiet"]
|
|
95
|
+
|
|
96
|
+
obj = ServerSettings.load()
|
|
97
|
+
data = _serialize(obj)
|
|
98
|
+
|
|
99
|
+
if dry_run:
|
|
100
|
+
if not quiet:
|
|
101
|
+
self.stdout.write("Dry run — current ServerSettings values:")
|
|
102
|
+
for field, value in data.items():
|
|
103
|
+
self.stdout.write(f" {field}: {value!r}")
|
|
104
|
+
return
|
|
105
|
+
|
|
106
|
+
if not output_path.parent.exists():
|
|
107
|
+
raise CommandError(f"Output directory does not exist: {output_path.parent}")
|
|
108
|
+
|
|
109
|
+
payload = {
|
|
110
|
+
"version": 1,
|
|
111
|
+
"meta": _build_meta("export_settings"),
|
|
112
|
+
"settings": data,
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
with output_path.open("w", encoding="utf-8") as f:
|
|
116
|
+
json.dump(payload, f, indent=2)
|
|
117
|
+
|
|
118
|
+
if not quiet:
|
|
119
|
+
self.stdout.write(self.style.SUCCESS(
|
|
120
|
+
f"ServerSettings exported to {output_path}."
|
|
121
|
+
))
|