MacroSignage 0.2.2__tar.gz → 0.2.4__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.
- {macrosignage-0.2.2/src/MacroSignage.egg-info → macrosignage-0.2.4}/PKG-INFO +23 -22
- {macrosignage-0.2.2 → macrosignage-0.2.4}/README.md +21 -21
- {macrosignage-0.2.2 → macrosignage-0.2.4}/pyproject.toml +2 -1
- {macrosignage-0.2.2 → macrosignage-0.2.4/src/MacroSignage.egg-info}/PKG-INFO +23 -22
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/MacroSignage.egg-info/SOURCES.txt +3 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/MacroSignage.egg-info/requires.txt +1 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/__init__.py +1 -1
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/app.py +10 -1
- macrosignage-0.2.4/src/macrosignage/features/admin/templates/admin/displays/claim.html +134 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/displays/list.html +10 -2
- macrosignage-0.2.4/src/macrosignage/features/admin/templates/admin/displays/scan.html +145 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/media/detail.html +31 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/media/form.html +42 -3
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/media/list.html +5 -1
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/api/routes.py +36 -2
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/api/serializers.py +3 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/displays/models.py +23 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/displays/routes.py +100 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/displays/services.py +72 -2
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/displays/templates/displays/player.html +7 -0
- macrosignage-0.2.4/src/macrosignage/features/displays/templates/displays/register.html +47 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/media/forms.py +38 -1
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/media/models.py +3 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/media/routes.py +9 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/media/services.py +10 -1
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/css/main.css +235 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/templates/layouts/admin.html +2 -2
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/web/templates/web/index.html +2 -2
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_api.py +19 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_client_app.py +26 -1
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_config.py +8 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_display_player.py +70 -1
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_docs.py +37 -11
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_release_workflows.py +18 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_slider_media.py +52 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/LICENSE +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/setup.cfg +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/MacroSignage.egg-info/dependency_links.txt +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/MacroSignage.egg-info/entry_points.txt +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/MacroSignage.egg-info/top_level.txt +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/cli.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/config.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/diagnostics.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/extensions.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/__init__.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/__init__.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/forms.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/models.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/routes.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/services.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/api_tokens/list.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/dashboard.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/database.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/displays/detail.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/displays/form.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/fonts/form.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/fonts/list.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/logo.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/schedules/detail.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/schedules/form.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/schedules/list.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/settings.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/users/detail.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/users/form.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/admin/templates/admin/users/list.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/api/__init__.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/associations.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/auth/__init__.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/auth/api_token_forms.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/auth/forms.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/auth/models.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/auth/permissions.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/auth/routes.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/auth/services.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/auth/templates/auth/login.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/auth/templates/auth/password_reset_form.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/auth/templates/auth/password_reset_request.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/auth/templates/auth/setup.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/auth/token_routes.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/displays/__init__.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/displays/forms.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/displays/templates/displays/maintenance.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/displays/templates/displays/offline.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/displays/templates/displays/pair_failed.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/displays/templates/displays/unauthorized.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/media/__init__.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/schedules/__init__.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/schedules/forms.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/schedules/models.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/schedules/routes.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/features/schedules/services.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/css/theme.css +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/img/bg/bg-dust-corner-bl.png +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/img/bg/bg-dust-corner-br.png +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/img/bg/bg-dust-corner-tl.png +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/img/bg/bg-dust-corner-tr.png +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/img/bg/bg-dust-overlay.png +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/img/bg/bg-dust-overlay.webp +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/img/bg/bg-mask.png +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/img/bg/bg-pattern-embedded.svg +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/img/bg/bg-pattern.svg +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/img/bg/bg-tile-1024.png +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/img/bg/bg-tile-1024.webp +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/js/display-player.js +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/js/main.js +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/vendor/animate/LICENSE +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/vendor/animate/animate.css +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/vendor/animate/animate.min.css +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/vendor/bootstrap/LICENSE +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/vendor/bootstrap/css/bootstrap.min.css +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/vendor/bootstrap/css/bootstrap.min.css.map +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/vendor/bootstrap/js/bootstrap.bundle.min.js +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/static/vendor/bootstrap/js/bootstrap.bundle.min.js.map +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/templates/errors/500.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/templates/layouts/_base.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/templates/layouts/auth.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/templates/pages/index.html +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/time_utils.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/web/__init__.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/src/macrosignage/web/routes.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_admin_crud.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_admin_dashboard.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_auth.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_cli.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_operational_readiness.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_production_hardening.py +0 -0
- {macrosignage-0.2.2 → macrosignage-0.2.4}/tests/test_v05_polish_scale.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MacroSignage
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Web-based Digital Signage System
|
|
5
5
|
Author-email: Javier Baez <baezdevs@gmail.com>
|
|
6
6
|
Maintainer-email: Javier Baez <baezdevs@gmail.com>
|
|
@@ -31,6 +31,7 @@ Requires-Dist: flask-login>=0.6.3
|
|
|
31
31
|
Requires-Dist: flask-wtf>=1.3.0
|
|
32
32
|
Requires-Dist: flask-sqlalchemy>=3.1.1
|
|
33
33
|
Requires-Dist: python-dotenv>=1.2.2
|
|
34
|
+
Requires-Dist: qrcode>=8.2
|
|
34
35
|
Requires-Dist: python-slugify>=8.0.4
|
|
35
36
|
Requires-Dist: email-validator>=2.3.0
|
|
36
37
|
Requires-Dist: python-usernames>=1.1.0
|
|
@@ -42,12 +43,12 @@ Dynamic: license-file
|
|
|
42
43
|
|
|
43
44
|
[](https://pypi.org/project/MacroSignage/)
|
|
44
45
|
[](https://pypi.org/project/MacroSignage/)
|
|
45
|
-
[](LICENSE)
|
|
46
|
+
[](https://github.com/BaezFJ/MacroSignage/blob/master/LICENSE)
|
|
46
47
|
[](https://github.com/BaezFJ/MacroSignage/actions/workflows/ci.yml)
|
|
47
48
|
|
|
48
49
|
MacroSignage is a Flask-based digital signage manager with an admin console, token-secured display players, scheduling, media playback, REST API access, and a standalone pywebview display client.
|
|
49
50
|
|
|
50
|
-
> **Status:** Pre-alpha v0.2.
|
|
51
|
+
> **Status:** Pre-alpha v0.2.4. Data models and API contracts can change before v1.0.
|
|
51
52
|
|
|
52
53
|
## Features
|
|
53
54
|
|
|
@@ -98,7 +99,7 @@ MACROSIGNAGE_SESSION_COOKIE_SECURE=true \
|
|
|
98
99
|
macrosignage-prod --host 127.0.0.1 --port 8080 --threads 4
|
|
99
100
|
```
|
|
100
101
|
|
|
101
|
-
See [Deployment](docs/deployment.md) for systemd, Docker, HTTPS, health checks, backups, restore, and rollback.
|
|
102
|
+
See [Deployment](https://github.com/BaezFJ/MacroSignage/blob/master/docs/deployment.md) for systemd, Docker, HTTPS, health checks, backups, restore, and rollback.
|
|
102
103
|
|
|
103
104
|
## Client Executables
|
|
104
105
|
|
|
@@ -108,26 +109,26 @@ Prebuilt standalone display client executables are available on the GitHub Relea
|
|
|
108
109
|
https://github.com/BaezFJ/MacroSignage/releases
|
|
109
110
|
```
|
|
110
111
|
|
|
111
|
-
The client source package lives in `client/`. See [Standalone Client](docs/client.md).
|
|
112
|
+
The client source package lives in `client/`. See [Standalone Client](https://github.com/BaezFJ/MacroSignage/blob/master/docs/client.md).
|
|
112
113
|
|
|
113
114
|
## Documentation
|
|
114
115
|
|
|
115
|
-
Start with [docs/index.md](docs/index.md).
|
|
116
|
+
Start with [docs/index.md](https://github.com/BaezFJ/MacroSignage/blob/master/docs/index.md).
|
|
116
117
|
|
|
117
118
|
Core guides:
|
|
118
119
|
|
|
119
|
-
- [Installation](docs/installation.md)
|
|
120
|
-
- [Configuration](docs/configuration.md)
|
|
121
|
-
- [Auth and RBAC](docs/auth-rbac.md)
|
|
122
|
-
- [Display Management and Player Pairing](docs/displays.md)
|
|
123
|
-
- [Media Library](docs/media.md)
|
|
124
|
-
- [Scheduling and Playback](docs/scheduling.md)
|
|
125
|
-
- [REST API](docs/rest-api.md)
|
|
126
|
-
- [API Tokens](docs/api-tokens.md)
|
|
127
|
-
- [Deployment](docs/deployment.md)
|
|
128
|
-
- [Troubleshooting](docs/troubleshooting.md)
|
|
129
|
-
- [Development](docs/development.md)
|
|
130
|
-
- [Architecture](docs/architecture.md)
|
|
120
|
+
- [Installation](https://github.com/BaezFJ/MacroSignage/blob/master/docs/installation.md)
|
|
121
|
+
- [Configuration](https://github.com/BaezFJ/MacroSignage/blob/master/docs/configuration.md)
|
|
122
|
+
- [Auth and RBAC](https://github.com/BaezFJ/MacroSignage/blob/master/docs/auth-rbac.md)
|
|
123
|
+
- [Display Management and Player Pairing](https://github.com/BaezFJ/MacroSignage/blob/master/docs/displays.md)
|
|
124
|
+
- [Media Library](https://github.com/BaezFJ/MacroSignage/blob/master/docs/media.md)
|
|
125
|
+
- [Scheduling and Playback](https://github.com/BaezFJ/MacroSignage/blob/master/docs/scheduling.md)
|
|
126
|
+
- [REST API](https://github.com/BaezFJ/MacroSignage/blob/master/docs/rest-api.md)
|
|
127
|
+
- [API Tokens](https://github.com/BaezFJ/MacroSignage/blob/master/docs/api-tokens.md)
|
|
128
|
+
- [Deployment](https://github.com/BaezFJ/MacroSignage/blob/master/docs/deployment.md)
|
|
129
|
+
- [Troubleshooting](https://github.com/BaezFJ/MacroSignage/blob/master/docs/troubleshooting.md)
|
|
130
|
+
- [Development](https://github.com/BaezFJ/MacroSignage/blob/master/docs/development.md)
|
|
131
|
+
- [Architecture](https://github.com/BaezFJ/MacroSignage/blob/master/docs/architecture.md)
|
|
131
132
|
|
|
132
133
|
## Development Commands
|
|
133
134
|
|
|
@@ -145,17 +146,17 @@ uv run twine check dist/*
|
|
|
145
146
|
- CI runs on pull requests and pushes to `main`.
|
|
146
147
|
- PyPI publishing runs when a `v*` tag is pushed.
|
|
147
148
|
- Client executable build and release workflows produce Windows, macOS, and Linux assets.
|
|
148
|
-
- Release documentation review is tracked in [the checklist](docs/release-documentation-checklist.md).
|
|
149
|
+
- Release documentation review is tracked in [the checklist](https://github.com/BaezFJ/MacroSignage/blob/master/docs/release-documentation-checklist.md).
|
|
149
150
|
|
|
150
151
|
## v1.0 Remaining Work
|
|
151
152
|
|
|
152
|
-
- [ ] Production-hardened and fully tested ([roadmap](docs/production-hardening-roadmap.md))
|
|
153
|
-
- [x] Complete documentation ([roadmap](docs/documentation-roadmap.md))
|
|
153
|
+
- [ ] Production-hardened and fully tested ([roadmap](https://github.com/BaezFJ/MacroSignage/blob/master/docs/production-hardening-roadmap.md))
|
|
154
|
+
- [x] Complete documentation ([roadmap](https://github.com/BaezFJ/MacroSignage/blob/master/docs/documentation-roadmap.md))
|
|
154
155
|
- [x] Deployment guides for Docker, systemd, health checks, backups, and rollback
|
|
155
156
|
|
|
156
157
|
## License
|
|
157
158
|
|
|
158
|
-
MacroSignage is licensed under the MIT License. See [LICENSE](LICENSE).
|
|
159
|
+
MacroSignage is licensed under the MIT License. See [LICENSE](https://github.com/BaezFJ/MacroSignage/blob/master/LICENSE).
|
|
159
160
|
|
|
160
161
|
Copyright (c) 2022 Javier Baez
|
|
161
162
|
|
|
@@ -2,12 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://pypi.org/project/MacroSignage/)
|
|
4
4
|
[](https://pypi.org/project/MacroSignage/)
|
|
5
|
-
[](LICENSE)
|
|
5
|
+
[](https://github.com/BaezFJ/MacroSignage/blob/master/LICENSE)
|
|
6
6
|
[](https://github.com/BaezFJ/MacroSignage/actions/workflows/ci.yml)
|
|
7
7
|
|
|
8
8
|
MacroSignage is a Flask-based digital signage manager with an admin console, token-secured display players, scheduling, media playback, REST API access, and a standalone pywebview display client.
|
|
9
9
|
|
|
10
|
-
> **Status:** Pre-alpha v0.2.
|
|
10
|
+
> **Status:** Pre-alpha v0.2.4. Data models and API contracts can change before v1.0.
|
|
11
11
|
|
|
12
12
|
## Features
|
|
13
13
|
|
|
@@ -58,7 +58,7 @@ MACROSIGNAGE_SESSION_COOKIE_SECURE=true \
|
|
|
58
58
|
macrosignage-prod --host 127.0.0.1 --port 8080 --threads 4
|
|
59
59
|
```
|
|
60
60
|
|
|
61
|
-
See [Deployment](docs/deployment.md) for systemd, Docker, HTTPS, health checks, backups, restore, and rollback.
|
|
61
|
+
See [Deployment](https://github.com/BaezFJ/MacroSignage/blob/master/docs/deployment.md) for systemd, Docker, HTTPS, health checks, backups, restore, and rollback.
|
|
62
62
|
|
|
63
63
|
## Client Executables
|
|
64
64
|
|
|
@@ -68,26 +68,26 @@ Prebuilt standalone display client executables are available on the GitHub Relea
|
|
|
68
68
|
https://github.com/BaezFJ/MacroSignage/releases
|
|
69
69
|
```
|
|
70
70
|
|
|
71
|
-
The client source package lives in `client/`. See [Standalone Client](docs/client.md).
|
|
71
|
+
The client source package lives in `client/`. See [Standalone Client](https://github.com/BaezFJ/MacroSignage/blob/master/docs/client.md).
|
|
72
72
|
|
|
73
73
|
## Documentation
|
|
74
74
|
|
|
75
|
-
Start with [docs/index.md](docs/index.md).
|
|
75
|
+
Start with [docs/index.md](https://github.com/BaezFJ/MacroSignage/blob/master/docs/index.md).
|
|
76
76
|
|
|
77
77
|
Core guides:
|
|
78
78
|
|
|
79
|
-
- [Installation](docs/installation.md)
|
|
80
|
-
- [Configuration](docs/configuration.md)
|
|
81
|
-
- [Auth and RBAC](docs/auth-rbac.md)
|
|
82
|
-
- [Display Management and Player Pairing](docs/displays.md)
|
|
83
|
-
- [Media Library](docs/media.md)
|
|
84
|
-
- [Scheduling and Playback](docs/scheduling.md)
|
|
85
|
-
- [REST API](docs/rest-api.md)
|
|
86
|
-
- [API Tokens](docs/api-tokens.md)
|
|
87
|
-
- [Deployment](docs/deployment.md)
|
|
88
|
-
- [Troubleshooting](docs/troubleshooting.md)
|
|
89
|
-
- [Development](docs/development.md)
|
|
90
|
-
- [Architecture](docs/architecture.md)
|
|
79
|
+
- [Installation](https://github.com/BaezFJ/MacroSignage/blob/master/docs/installation.md)
|
|
80
|
+
- [Configuration](https://github.com/BaezFJ/MacroSignage/blob/master/docs/configuration.md)
|
|
81
|
+
- [Auth and RBAC](https://github.com/BaezFJ/MacroSignage/blob/master/docs/auth-rbac.md)
|
|
82
|
+
- [Display Management and Player Pairing](https://github.com/BaezFJ/MacroSignage/blob/master/docs/displays.md)
|
|
83
|
+
- [Media Library](https://github.com/BaezFJ/MacroSignage/blob/master/docs/media.md)
|
|
84
|
+
- [Scheduling and Playback](https://github.com/BaezFJ/MacroSignage/blob/master/docs/scheduling.md)
|
|
85
|
+
- [REST API](https://github.com/BaezFJ/MacroSignage/blob/master/docs/rest-api.md)
|
|
86
|
+
- [API Tokens](https://github.com/BaezFJ/MacroSignage/blob/master/docs/api-tokens.md)
|
|
87
|
+
- [Deployment](https://github.com/BaezFJ/MacroSignage/blob/master/docs/deployment.md)
|
|
88
|
+
- [Troubleshooting](https://github.com/BaezFJ/MacroSignage/blob/master/docs/troubleshooting.md)
|
|
89
|
+
- [Development](https://github.com/BaezFJ/MacroSignage/blob/master/docs/development.md)
|
|
90
|
+
- [Architecture](https://github.com/BaezFJ/MacroSignage/blob/master/docs/architecture.md)
|
|
91
91
|
|
|
92
92
|
## Development Commands
|
|
93
93
|
|
|
@@ -105,17 +105,17 @@ uv run twine check dist/*
|
|
|
105
105
|
- CI runs on pull requests and pushes to `main`.
|
|
106
106
|
- PyPI publishing runs when a `v*` tag is pushed.
|
|
107
107
|
- Client executable build and release workflows produce Windows, macOS, and Linux assets.
|
|
108
|
-
- Release documentation review is tracked in [the checklist](docs/release-documentation-checklist.md).
|
|
108
|
+
- Release documentation review is tracked in [the checklist](https://github.com/BaezFJ/MacroSignage/blob/master/docs/release-documentation-checklist.md).
|
|
109
109
|
|
|
110
110
|
## v1.0 Remaining Work
|
|
111
111
|
|
|
112
|
-
- [ ] Production-hardened and fully tested ([roadmap](docs/production-hardening-roadmap.md))
|
|
113
|
-
- [x] Complete documentation ([roadmap](docs/documentation-roadmap.md))
|
|
112
|
+
- [ ] Production-hardened and fully tested ([roadmap](https://github.com/BaezFJ/MacroSignage/blob/master/docs/production-hardening-roadmap.md))
|
|
113
|
+
- [x] Complete documentation ([roadmap](https://github.com/BaezFJ/MacroSignage/blob/master/docs/documentation-roadmap.md))
|
|
114
114
|
- [x] Deployment guides for Docker, systemd, health checks, backups, and rollback
|
|
115
115
|
|
|
116
116
|
## License
|
|
117
117
|
|
|
118
|
-
MacroSignage is licensed under the MIT License. See [LICENSE](LICENSE).
|
|
118
|
+
MacroSignage is licensed under the MIT License. See [LICENSE](https://github.com/BaezFJ/MacroSignage/blob/master/LICENSE).
|
|
119
119
|
|
|
120
120
|
Copyright (c) 2022 Javier Baez
|
|
121
121
|
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "MacroSignage"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.4"
|
|
8
8
|
description = "Web-based Digital Signage System"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "MIT"
|
|
@@ -44,6 +44,7 @@ dependencies = [
|
|
|
44
44
|
"flask-wtf>=1.3.0",
|
|
45
45
|
"flask-sqlalchemy>=3.1.1",
|
|
46
46
|
"python-dotenv>=1.2.2",
|
|
47
|
+
"qrcode>=8.2",
|
|
47
48
|
"python-slugify>=8.0.4",
|
|
48
49
|
"email-validator>=2.3.0",
|
|
49
50
|
"python-usernames>=1.1.0",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: MacroSignage
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Web-based Digital Signage System
|
|
5
5
|
Author-email: Javier Baez <baezdevs@gmail.com>
|
|
6
6
|
Maintainer-email: Javier Baez <baezdevs@gmail.com>
|
|
@@ -31,6 +31,7 @@ Requires-Dist: flask-login>=0.6.3
|
|
|
31
31
|
Requires-Dist: flask-wtf>=1.3.0
|
|
32
32
|
Requires-Dist: flask-sqlalchemy>=3.1.1
|
|
33
33
|
Requires-Dist: python-dotenv>=1.2.2
|
|
34
|
+
Requires-Dist: qrcode>=8.2
|
|
34
35
|
Requires-Dist: python-slugify>=8.0.4
|
|
35
36
|
Requires-Dist: email-validator>=2.3.0
|
|
36
37
|
Requires-Dist: python-usernames>=1.1.0
|
|
@@ -42,12 +43,12 @@ Dynamic: license-file
|
|
|
42
43
|
|
|
43
44
|
[](https://pypi.org/project/MacroSignage/)
|
|
44
45
|
[](https://pypi.org/project/MacroSignage/)
|
|
45
|
-
[](LICENSE)
|
|
46
|
+
[](https://github.com/BaezFJ/MacroSignage/blob/master/LICENSE)
|
|
46
47
|
[](https://github.com/BaezFJ/MacroSignage/actions/workflows/ci.yml)
|
|
47
48
|
|
|
48
49
|
MacroSignage is a Flask-based digital signage manager with an admin console, token-secured display players, scheduling, media playback, REST API access, and a standalone pywebview display client.
|
|
49
50
|
|
|
50
|
-
> **Status:** Pre-alpha v0.2.
|
|
51
|
+
> **Status:** Pre-alpha v0.2.4. Data models and API contracts can change before v1.0.
|
|
51
52
|
|
|
52
53
|
## Features
|
|
53
54
|
|
|
@@ -98,7 +99,7 @@ MACROSIGNAGE_SESSION_COOKIE_SECURE=true \
|
|
|
98
99
|
macrosignage-prod --host 127.0.0.1 --port 8080 --threads 4
|
|
99
100
|
```
|
|
100
101
|
|
|
101
|
-
See [Deployment](docs/deployment.md) for systemd, Docker, HTTPS, health checks, backups, restore, and rollback.
|
|
102
|
+
See [Deployment](https://github.com/BaezFJ/MacroSignage/blob/master/docs/deployment.md) for systemd, Docker, HTTPS, health checks, backups, restore, and rollback.
|
|
102
103
|
|
|
103
104
|
## Client Executables
|
|
104
105
|
|
|
@@ -108,26 +109,26 @@ Prebuilt standalone display client executables are available on the GitHub Relea
|
|
|
108
109
|
https://github.com/BaezFJ/MacroSignage/releases
|
|
109
110
|
```
|
|
110
111
|
|
|
111
|
-
The client source package lives in `client/`. See [Standalone Client](docs/client.md).
|
|
112
|
+
The client source package lives in `client/`. See [Standalone Client](https://github.com/BaezFJ/MacroSignage/blob/master/docs/client.md).
|
|
112
113
|
|
|
113
114
|
## Documentation
|
|
114
115
|
|
|
115
|
-
Start with [docs/index.md](docs/index.md).
|
|
116
|
+
Start with [docs/index.md](https://github.com/BaezFJ/MacroSignage/blob/master/docs/index.md).
|
|
116
117
|
|
|
117
118
|
Core guides:
|
|
118
119
|
|
|
119
|
-
- [Installation](docs/installation.md)
|
|
120
|
-
- [Configuration](docs/configuration.md)
|
|
121
|
-
- [Auth and RBAC](docs/auth-rbac.md)
|
|
122
|
-
- [Display Management and Player Pairing](docs/displays.md)
|
|
123
|
-
- [Media Library](docs/media.md)
|
|
124
|
-
- [Scheduling and Playback](docs/scheduling.md)
|
|
125
|
-
- [REST API](docs/rest-api.md)
|
|
126
|
-
- [API Tokens](docs/api-tokens.md)
|
|
127
|
-
- [Deployment](docs/deployment.md)
|
|
128
|
-
- [Troubleshooting](docs/troubleshooting.md)
|
|
129
|
-
- [Development](docs/development.md)
|
|
130
|
-
- [Architecture](docs/architecture.md)
|
|
120
|
+
- [Installation](https://github.com/BaezFJ/MacroSignage/blob/master/docs/installation.md)
|
|
121
|
+
- [Configuration](https://github.com/BaezFJ/MacroSignage/blob/master/docs/configuration.md)
|
|
122
|
+
- [Auth and RBAC](https://github.com/BaezFJ/MacroSignage/blob/master/docs/auth-rbac.md)
|
|
123
|
+
- [Display Management and Player Pairing](https://github.com/BaezFJ/MacroSignage/blob/master/docs/displays.md)
|
|
124
|
+
- [Media Library](https://github.com/BaezFJ/MacroSignage/blob/master/docs/media.md)
|
|
125
|
+
- [Scheduling and Playback](https://github.com/BaezFJ/MacroSignage/blob/master/docs/scheduling.md)
|
|
126
|
+
- [REST API](https://github.com/BaezFJ/MacroSignage/blob/master/docs/rest-api.md)
|
|
127
|
+
- [API Tokens](https://github.com/BaezFJ/MacroSignage/blob/master/docs/api-tokens.md)
|
|
128
|
+
- [Deployment](https://github.com/BaezFJ/MacroSignage/blob/master/docs/deployment.md)
|
|
129
|
+
- [Troubleshooting](https://github.com/BaezFJ/MacroSignage/blob/master/docs/troubleshooting.md)
|
|
130
|
+
- [Development](https://github.com/BaezFJ/MacroSignage/blob/master/docs/development.md)
|
|
131
|
+
- [Architecture](https://github.com/BaezFJ/MacroSignage/blob/master/docs/architecture.md)
|
|
131
132
|
|
|
132
133
|
## Development Commands
|
|
133
134
|
|
|
@@ -145,17 +146,17 @@ uv run twine check dist/*
|
|
|
145
146
|
- CI runs on pull requests and pushes to `main`.
|
|
146
147
|
- PyPI publishing runs when a `v*` tag is pushed.
|
|
147
148
|
- Client executable build and release workflows produce Windows, macOS, and Linux assets.
|
|
148
|
-
- Release documentation review is tracked in [the checklist](docs/release-documentation-checklist.md).
|
|
149
|
+
- Release documentation review is tracked in [the checklist](https://github.com/BaezFJ/MacroSignage/blob/master/docs/release-documentation-checklist.md).
|
|
149
150
|
|
|
150
151
|
## v1.0 Remaining Work
|
|
151
152
|
|
|
152
|
-
- [ ] Production-hardened and fully tested ([roadmap](docs/production-hardening-roadmap.md))
|
|
153
|
-
- [x] Complete documentation ([roadmap](docs/documentation-roadmap.md))
|
|
153
|
+
- [ ] Production-hardened and fully tested ([roadmap](https://github.com/BaezFJ/MacroSignage/blob/master/docs/production-hardening-roadmap.md))
|
|
154
|
+
- [x] Complete documentation ([roadmap](https://github.com/BaezFJ/MacroSignage/blob/master/docs/documentation-roadmap.md))
|
|
154
155
|
- [x] Deployment guides for Docker, systemd, health checks, backups, and rollback
|
|
155
156
|
|
|
156
157
|
## License
|
|
157
158
|
|
|
158
|
-
MacroSignage is licensed under the MIT License. See [LICENSE](LICENSE).
|
|
159
|
+
MacroSignage is licensed under the MIT License. See [LICENSE](https://github.com/BaezFJ/MacroSignage/blob/master/LICENSE).
|
|
159
160
|
|
|
160
161
|
Copyright (c) 2022 Javier Baez
|
|
161
162
|
|
|
@@ -26,9 +26,11 @@ src/macrosignage/features/admin/templates/admin/database.html
|
|
|
26
26
|
src/macrosignage/features/admin/templates/admin/logo.html
|
|
27
27
|
src/macrosignage/features/admin/templates/admin/settings.html
|
|
28
28
|
src/macrosignage/features/admin/templates/admin/api_tokens/list.html
|
|
29
|
+
src/macrosignage/features/admin/templates/admin/displays/claim.html
|
|
29
30
|
src/macrosignage/features/admin/templates/admin/displays/detail.html
|
|
30
31
|
src/macrosignage/features/admin/templates/admin/displays/form.html
|
|
31
32
|
src/macrosignage/features/admin/templates/admin/displays/list.html
|
|
33
|
+
src/macrosignage/features/admin/templates/admin/displays/scan.html
|
|
32
34
|
src/macrosignage/features/admin/templates/admin/fonts/form.html
|
|
33
35
|
src/macrosignage/features/admin/templates/admin/fonts/list.html
|
|
34
36
|
src/macrosignage/features/admin/templates/admin/media/detail.html
|
|
@@ -64,6 +66,7 @@ src/macrosignage/features/displays/templates/displays/maintenance.html
|
|
|
64
66
|
src/macrosignage/features/displays/templates/displays/offline.html
|
|
65
67
|
src/macrosignage/features/displays/templates/displays/pair_failed.html
|
|
66
68
|
src/macrosignage/features/displays/templates/displays/player.html
|
|
69
|
+
src/macrosignage/features/displays/templates/displays/register.html
|
|
67
70
|
src/macrosignage/features/displays/templates/displays/unauthorized.html
|
|
68
71
|
src/macrosignage/features/media/__init__.py
|
|
69
72
|
src/macrosignage/features/media/forms.py
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
__version__ = "0.2.
|
|
1
|
+
__version__ = "0.2.4"
|
|
2
2
|
|
|
3
3
|
import os
|
|
4
4
|
from os import PathLike
|
|
@@ -111,6 +111,15 @@ def ensure_runtime_schema() -> None:
|
|
|
111
111
|
if "text_animation" not in columns:
|
|
112
112
|
statements.append("ALTER TABLE media_slides ADD COLUMN text_animation VARCHAR(40) NOT NULL DEFAULT 'NONE'")
|
|
113
113
|
|
|
114
|
+
if "media_assets" in tables:
|
|
115
|
+
columns = {column["name"] for column in inspector.get_columns("media_assets")}
|
|
116
|
+
if "neon_text_color" not in columns:
|
|
117
|
+
statements.append("ALTER TABLE media_assets ADD COLUMN neon_text_color VARCHAR(7)")
|
|
118
|
+
if "neon_frame_color" not in columns:
|
|
119
|
+
statements.append("ALTER TABLE media_assets ADD COLUMN neon_frame_color VARCHAR(7)")
|
|
120
|
+
if "neon_background_color" not in columns:
|
|
121
|
+
statements.append("ALTER TABLE media_assets ADD COLUMN neon_background_color VARCHAR(7)")
|
|
122
|
+
|
|
114
123
|
if "displays" in tables:
|
|
115
124
|
columns = {column["name"] for column in inspector.get_columns("displays")}
|
|
116
125
|
if "player_token_hash" not in columns:
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
{% extends 'layouts/admin.html' %}
|
|
2
|
+
|
|
3
|
+
{% block main %}
|
|
4
|
+
<div class="admin-page-header">
|
|
5
|
+
<div>
|
|
6
|
+
<p class="eyebrow">Display Management</p>
|
|
7
|
+
<h1 class="h2 mb-1">{{ title }}</h1>
|
|
8
|
+
<p class="text-secondary mb-0">Create a display record for the screen waiting on the QR registration page.</p>
|
|
9
|
+
</div>
|
|
10
|
+
<a class="btn btn-outline-secondary" href="{{ url_for('admin_displays.list_displays') }}">Back to displays</a>
|
|
11
|
+
</div>
|
|
12
|
+
|
|
13
|
+
<form method="post" action="{{ form_action }}" novalidate>
|
|
14
|
+
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
|
15
|
+
<div class="row g-3">
|
|
16
|
+
<div class="col-lg-8">
|
|
17
|
+
<section class="card">
|
|
18
|
+
<div class="card-body">
|
|
19
|
+
<h2 class="h5 mb-3">Display Details</h2>
|
|
20
|
+
<div class="mb-3">
|
|
21
|
+
<label class="form-label" for="displayName">Name</label>
|
|
22
|
+
<input id="displayName"
|
|
23
|
+
class="form-control {% if errors.get('name') %}is-invalid{% endif %}"
|
|
24
|
+
type="text"
|
|
25
|
+
name="name"
|
|
26
|
+
value="{{ display.name or '' }}"
|
|
27
|
+
required
|
|
28
|
+
autocomplete="off"
|
|
29
|
+
autofocus>
|
|
30
|
+
{% if errors.get('name') %}
|
|
31
|
+
<div class="invalid-feedback">{{ errors.name }}</div>
|
|
32
|
+
{% endif %}
|
|
33
|
+
</div>
|
|
34
|
+
|
|
35
|
+
<div class="mb-3">
|
|
36
|
+
<label class="form-label" for="displayLocation">Location</label>
|
|
37
|
+
<input id="displayLocation"
|
|
38
|
+
class="form-control"
|
|
39
|
+
type="text"
|
|
40
|
+
name="location"
|
|
41
|
+
value="{{ display.location or '' }}"
|
|
42
|
+
placeholder="Lobby, front window, conference room">
|
|
43
|
+
</div>
|
|
44
|
+
|
|
45
|
+
<div>
|
|
46
|
+
<label class="form-label" for="displayNotes">Notes</label>
|
|
47
|
+
<textarea id="displayNotes"
|
|
48
|
+
class="form-control"
|
|
49
|
+
name="notes"
|
|
50
|
+
rows="5"
|
|
51
|
+
placeholder="Installation notes, device details, or maintenance context">{{ display.notes or '' }}</textarea>
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
</section>
|
|
55
|
+
</div>
|
|
56
|
+
|
|
57
|
+
<div class="col-lg-4">
|
|
58
|
+
<section class="card mb-3">
|
|
59
|
+
<div class="card-body">
|
|
60
|
+
<h2 class="h5 mb-3">Playback Profile</h2>
|
|
61
|
+
<div class="mb-3">
|
|
62
|
+
<label class="form-label" for="displayStatusForm">Status</label>
|
|
63
|
+
<select id="displayStatusForm"
|
|
64
|
+
class="form-select {% if errors.get('status') %}is-invalid{% endif %}"
|
|
65
|
+
name="status">
|
|
66
|
+
{% for value, label in display_statuses.items() %}
|
|
67
|
+
<option value="{{ value }}" {% if display.status == value %}selected{% endif %}>{{ label }}</option>
|
|
68
|
+
{% endfor %}
|
|
69
|
+
</select>
|
|
70
|
+
{% if errors.get('status') %}
|
|
71
|
+
<div class="invalid-feedback">{{ errors.status }}</div>
|
|
72
|
+
{% endif %}
|
|
73
|
+
</div>
|
|
74
|
+
|
|
75
|
+
<div class="mb-3">
|
|
76
|
+
<label class="form-label" for="displayOrientation">Orientation</label>
|
|
77
|
+
<select id="displayOrientation"
|
|
78
|
+
class="form-select {% if errors.get('orientation') %}is-invalid{% endif %}"
|
|
79
|
+
name="orientation">
|
|
80
|
+
{% for value, label in display_orientations.items() %}
|
|
81
|
+
<option value="{{ value }}" {% if display.orientation == value %}selected{% endif %}>{{ label }}</option>
|
|
82
|
+
{% endfor %}
|
|
83
|
+
</select>
|
|
84
|
+
{% if errors.get('orientation') %}
|
|
85
|
+
<div class="invalid-feedback">{{ errors.orientation }}</div>
|
|
86
|
+
{% endif %}
|
|
87
|
+
</div>
|
|
88
|
+
|
|
89
|
+
<div class="row g-2">
|
|
90
|
+
<div class="col-6">
|
|
91
|
+
<label class="form-label" for="resolutionWidth">Width</label>
|
|
92
|
+
<input id="resolutionWidth"
|
|
93
|
+
class="form-control {% if errors.get('resolution_width') %}is-invalid{% endif %}"
|
|
94
|
+
type="number"
|
|
95
|
+
min="1"
|
|
96
|
+
step="1"
|
|
97
|
+
name="resolution_width"
|
|
98
|
+
value="{{ display.resolution_width }}">
|
|
99
|
+
{% if errors.get('resolution_width') %}
|
|
100
|
+
<div class="invalid-feedback">{{ errors.resolution_width }}</div>
|
|
101
|
+
{% endif %}
|
|
102
|
+
</div>
|
|
103
|
+
<div class="col-6">
|
|
104
|
+
<label class="form-label" for="resolutionHeight">Height</label>
|
|
105
|
+
<input id="resolutionHeight"
|
|
106
|
+
class="form-control {% if errors.get('resolution_height') %}is-invalid{% endif %}"
|
|
107
|
+
type="number"
|
|
108
|
+
min="1"
|
|
109
|
+
step="1"
|
|
110
|
+
name="resolution_height"
|
|
111
|
+
value="{{ display.resolution_height }}">
|
|
112
|
+
{% if errors.get('resolution_height') %}
|
|
113
|
+
<div class="invalid-feedback">{{ errors.resolution_height }}</div>
|
|
114
|
+
{% endif %}
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</section>
|
|
119
|
+
|
|
120
|
+
<section class="card mb-3">
|
|
121
|
+
<div class="card-body">
|
|
122
|
+
<h2 class="h5 mb-2">QR Claim</h2>
|
|
123
|
+
<p class="text-secondary mb-0">Expires {{ registration.expires_at.strftime('%b %d, %Y %I:%M %p') }}.</p>
|
|
124
|
+
</div>
|
|
125
|
+
</section>
|
|
126
|
+
|
|
127
|
+
<div class="d-grid gap-2">
|
|
128
|
+
<button class="btn btn-primary" type="submit">{{ submit_label }}</button>
|
|
129
|
+
<a class="btn btn-outline-secondary" href="{{ url_for('admin_displays.list_displays') }}">Cancel</a>
|
|
130
|
+
</div>
|
|
131
|
+
</div>
|
|
132
|
+
</div>
|
|
133
|
+
</form>
|
|
134
|
+
{% endblock %}
|
|
@@ -7,7 +7,11 @@
|
|
|
7
7
|
<h1 class="h2 mb-1">Displays</h1>
|
|
8
8
|
<p class="text-secondary mb-0">Register screens and track their playback readiness.</p>
|
|
9
9
|
</div>
|
|
10
|
-
<
|
|
10
|
+
<div class="d-flex flex-wrap gap-2">
|
|
11
|
+
<a class="btn btn-outline-secondary" href="{{ url_for('admin_displays.scan_display_qr') }}">Scan QR code</a>
|
|
12
|
+
<a class="btn btn-outline-secondary" href="{{ url_for('display_player.register_display_player') }}" target="_blank" rel="noopener">Open QR setup</a>
|
|
13
|
+
<a class="btn btn-primary" href="{{ url_for('admin_displays.create_display') }}">Add display</a>
|
|
14
|
+
</div>
|
|
11
15
|
</div>
|
|
12
16
|
|
|
13
17
|
<section class="card mb-3" aria-label="Display filters">
|
|
@@ -91,7 +95,11 @@
|
|
|
91
95
|
<div>
|
|
92
96
|
<p class="mb-1 fw-semibold">No displays found</p>
|
|
93
97
|
<p class="mb-3 text-secondary">Register a display to start managing screen inventory.</p>
|
|
94
|
-
<
|
|
98
|
+
<div class="d-flex flex-wrap justify-content-center gap-2">
|
|
99
|
+
<a class="btn btn-outline-secondary" href="{{ url_for('admin_displays.scan_display_qr') }}">Scan QR code</a>
|
|
100
|
+
<a class="btn btn-outline-secondary" href="{{ url_for('display_player.register_display_player') }}" target="_blank" rel="noopener">Open QR setup</a>
|
|
101
|
+
<a class="btn btn-primary" href="{{ url_for('admin_displays.create_display') }}">Add display</a>
|
|
102
|
+
</div>
|
|
95
103
|
</div>
|
|
96
104
|
</div>
|
|
97
105
|
</div>
|