gams-frog 0.3.0__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.
- gams_frog-0.3.0/.gitignore +15 -0
- gams_frog-0.3.0/.gitlab-ci.yml +57 -0
- gams_frog-0.3.0/CHANGELOG.md +27 -0
- gams_frog-0.3.0/LICENSE.md +21 -0
- gams_frog-0.3.0/Makefile +16 -0
- gams_frog-0.3.0/PKG-INFO +128 -0
- gams_frog-0.3.0/README.md +106 -0
- gams_frog-0.3.0/pyproject.toml +47 -0
- gams_frog-0.3.0/src/gams_frog/__init__.py +2 -0
- gams_frog-0.3.0/src/gams_frog/cli.py +229 -0
- gams_frog-0.3.0/src/gams_frog/deploy/AuthorizationService.py +80 -0
- gams_frog-0.3.0/src/gams_frog/deploy/DeployService.py +148 -0
- gams_frog-0.3.0/src/gams_frog/deploy/GamsAuthClient.py +75 -0
- gams_frog-0.3.0/src/gams_frog/deploy/LoginFormParser.py +39 -0
- gams_frog-0.3.0/src/gams_frog/deploy/__init__.py +0 -0
- gams_frog-0.3.0/src/gams_frog/ssr/__init__.py +0 -0
- gams_frog-0.3.0/src/gams_frog/ssr/init/AppInitializer.py +106 -0
- gams_frog-0.3.0/src/gams_frog/ssr/init/ApplicationContext.py +36 -0
- gams_frog-0.3.0/src/gams_frog/ssr/init/__init__.py +0 -0
- gams_frog-0.3.0/src/gams_frog/ssr/init/config/AppEnv.py +23 -0
- gams_frog-0.3.0/src/gams_frog/ssr/init/config/ApplicationCacheConfig.py +20 -0
- gams_frog-0.3.0/src/gams_frog/ssr/init/config/ApplicationConfiguration.py +147 -0
- gams_frog-0.3.0/src/gams_frog/ssr/init/config/ApplicationExternalConfig.py +226 -0
- gams_frog-0.3.0/src/gams_frog/ssr/init/config/ApplicationExternalConfigImporter.py +103 -0
- gams_frog-0.3.0/src/gams_frog/ssr/init/config/__init__.py +0 -0
- gams_frog-0.3.0/src/gams_frog/ssr/load/ApplicationDataLoader.py +102 -0
- gams_frog-0.3.0/src/gams_frog/ssr/load/ApplicationDatastore.py +85 -0
- gams_frog-0.3.0/src/gams_frog/ssr/load/DigitalObjectService.py +49 -0
- gams_frog-0.3.0/src/gams_frog/ssr/load/ProjectService.py +23 -0
- gams_frog-0.3.0/src/gams_frog/ssr/load/__init__.py +0 -0
- gams_frog-0.3.0/src/gams_frog/ssr/load/cache/DataCacheManager.py +248 -0
- gams_frog-0.3.0/src/gams_frog/ssr/load/cache/__init__.py +0 -0
- gams_frog-0.3.0/src/gams_frog/ssr/load/utils/Pyrilo.py +199 -0
- gams_frog-0.3.0/src/gams_frog/ssr/load/utils/__init__.py +0 -0
- gams_frog-0.3.0/src/gams_frog/ssr/watch/ApplicationViewFileEventController.py +74 -0
- gams_frog-0.3.0/src/gams_frog/ssr/watch/ApplicationViewFileWatcher.py +37 -0
- gams_frog-0.3.0/src/gams_frog/ssr/watch/ApplicationWebServer.py +66 -0
- gams_frog-0.3.0/src/gams_frog/ssr/watch/__init__.py +0 -0
- gams_frog-0.3.0/src/gams_frog/ssr/watch/render/ApplicationErrorHtmlBuilder.py +14 -0
- gams_frog-0.3.0/src/gams_frog/ssr/watch/render/ApplicationStaticFileRenderer.py +72 -0
- gams_frog-0.3.0/src/gams_frog/ssr/watch/render/ApplicationViewTemplateRenderer.py +111 -0
- gams_frog-0.3.0/src/gams_frog/ssr/watch/render/DigitalObjectViewRenderer.py +182 -0
- gams_frog-0.3.0/src/gams_frog/ssr/watch/render/__init__.py +0 -0
- gams_frog-0.3.0/src/gams_frog/ssr/watch/utils/RenderUtils.py +19 -0
- gams_frog-0.3.0/src/gams_frog/ssr/watch/utils/__init__.py +0 -0
- gams_frog-0.3.0/src/gams_frog/validation/HardcodedPathVisitor.py +69 -0
- gams_frog-0.3.0/src/gams_frog/validation/JinjaTemplateValidator.py +71 -0
- gams_frog-0.3.0/src/gams_frog/validation/StaticFileValidator.py +98 -0
- gams_frog-0.3.0/src/gams_frog/validation/ValidationStatics.py +14 -0
- gams_frog-0.3.0/src/gams_frog/validation/__init__.py +0 -0
- gams_frog-0.3.0/tests/__init__.py +0 -0
- gams_frog-0.3.0/tests/conftest.py +92 -0
- gams_frog-0.3.0/tests/integration_tests/__init__.py +0 -0
- gams_frog-0.3.0/tests/integration_tests/test_build_cmd.py +144 -0
- gams_frog-0.3.0/tests/integration_tests/test_deploy.py +109 -0
- gams_frog-0.3.0/tests/integration_tests/test_project_template.py +35 -0
- gams_frog-0.3.0/tests/integration_tests/test_static_files.py +27 -0
- gams_frog-0.3.0/tests/integration_tests/test_validation.py +134 -0
- gams_frog-0.3.0/tests/pytest.ini +4 -0
- gams_frog-0.3.0/tests/resources/readme.md +1 -0
- gams_frog-0.3.0/tests/resources/test/templates/object-list.j2 +3 -0
- gams_frog-0.3.0/tests/resources/test/templates/object.j2 +2 -0
- gams_frog-0.3.0/tests/resources/test/templates/project.j2 +3 -0
- gams_frog-0.3.0/tests/unittests/__init__.py +0 -0
- gams_frog-0.3.0/tests/unittests/test_config.py +97 -0
- gams_frog-0.3.0/tests/unittests/test_datastore.py +39 -0
- gams_frog-0.3.0/tests/unittests/test_rendering.py +35 -0
- gams_frog-0.3.0/tests/utils/TestDatastream.py +30 -0
- gams_frog-0.3.0/tests/utils/TestDigitalObject.py +37 -0
- gams_frog-0.3.0/tests/utils/TestDigitalObjectViewModel.py +17 -0
- gams_frog-0.3.0/tests/utils/TestGamsFrogProject.py +190 -0
- gams_frog-0.3.0/tests/utils/TestProject.py +15 -0
- gams_frog-0.3.0/tests/utils/__init__.py +0 -0
- gams_frog-0.3.0/uv.lock +840 -0
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
variables:
|
|
2
|
+
UV_VERSION: 0.5
|
|
3
|
+
PYTHON_BASE_VERSION: 3.12
|
|
4
|
+
BASE_LAYER: bookworm-slim
|
|
5
|
+
|
|
6
|
+
stages:
|
|
7
|
+
- test
|
|
8
|
+
- lint
|
|
9
|
+
- build
|
|
10
|
+
- publish
|
|
11
|
+
|
|
12
|
+
# A hidden job template that can be used by different Python versions
|
|
13
|
+
.test-template:
|
|
14
|
+
stage: test
|
|
15
|
+
image: ghcr.io/astral-sh/uv:$UV_VERSION-python$PYTHON_BASE_VERSION-$BASE_LAYER
|
|
16
|
+
script:
|
|
17
|
+
- echo "uv environment version"
|
|
18
|
+
- uv --version
|
|
19
|
+
- echo "Pinning ${PYTHON_VERSION}"
|
|
20
|
+
- uv python pin ${PYTHON_VERSION}
|
|
21
|
+
- uv sync
|
|
22
|
+
- echo "Using python version:"
|
|
23
|
+
- python --version
|
|
24
|
+
- echo "Running tests with uv"
|
|
25
|
+
- uv run pytest tests
|
|
26
|
+
|
|
27
|
+
# Specific jobs for Python versions
|
|
28
|
+
test-py_3.12:
|
|
29
|
+
extends: .test-template
|
|
30
|
+
variables:
|
|
31
|
+
PYTHON_VERSION: "3.12"
|
|
32
|
+
|
|
33
|
+
lint:
|
|
34
|
+
stage: lint
|
|
35
|
+
image: ghcr.io/astral-sh/uv:$UV_VERSION-python$PYTHON_BASE_VERSION-$BASE_LAYER
|
|
36
|
+
script:
|
|
37
|
+
- echo "uv environment version"
|
|
38
|
+
- uv --version
|
|
39
|
+
- echo "Using python version:"
|
|
40
|
+
- python --version
|
|
41
|
+
- echo "Running uv check with ruff"
|
|
42
|
+
- uv run ruff check src
|
|
43
|
+
|
|
44
|
+
build:
|
|
45
|
+
stage: build
|
|
46
|
+
image: ghcr.io/astral-sh/uv:$UV_VERSION-python$PYTHON_BASE_VERSION-$BASE_LAYER
|
|
47
|
+
script:
|
|
48
|
+
uv build
|
|
49
|
+
|
|
50
|
+
publish-pypi:
|
|
51
|
+
stage: publish
|
|
52
|
+
image: ghcr.io/astral-sh/uv:$UV_VERSION-python$PYTHON_BASE_VERSION-$BASE_LAYER
|
|
53
|
+
script:
|
|
54
|
+
- uv build
|
|
55
|
+
- uv publish --token $PYPI_TOKEN
|
|
56
|
+
rules:
|
|
57
|
+
- if: $CI_COMMIT_TAG =~ /^v\d+\.\d+\.\d+$/
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.0.3]
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- renamed tool to gams-frog (from pollin-tool)
|
|
13
|
+
|
|
14
|
+
## [0.0.2] - 13.04.2026 [YANKED]
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- cli commands now default for gams-frog.toml to the current working directory of gams-frog
|
|
19
|
+
- added --version command
|
|
20
|
+
- corrected readme (for deployed tool)
|
|
21
|
+
|
|
22
|
+
## [0.0.1] - 13.04.2026 [YANKED]
|
|
23
|
+
|
|
24
|
+
### Added
|
|
25
|
+
|
|
26
|
+
- release of initial beta version of the software
|
|
27
|
+
- core features with SSR rendering with GAMS5
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sebastian David Schiller-Stoff
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
gams_frog-0.3.0/Makefile
ADDED
gams_frog-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: gams-frog
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: CLI tool for frontend generation for GAMS5 projects
|
|
5
|
+
Project-URL: Repository, https://zimlab.uni-graz.at/gams5/production/postprocessing/gams-frog
|
|
6
|
+
Author-email: Sebastian David Schiller-Stoff <sebastian.stoff@uni-graz.at>
|
|
7
|
+
License: MIT
|
|
8
|
+
License-File: LICENSE.md
|
|
9
|
+
Keywords: digital-humanities,gams,jinja2,static-site-generator
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Classifier: Topic :: Internet :: WWW/HTTP :: Site Management
|
|
15
|
+
Requires-Python: >=3.12
|
|
16
|
+
Requires-Dist: aiohttp>=3.13.3
|
|
17
|
+
Requires-Dist: click>=8.3.1
|
|
18
|
+
Requires-Dist: jinja2==3.1.6
|
|
19
|
+
Requires-Dist: requests>=2.32.4
|
|
20
|
+
Requires-Dist: watchdog>=6.0.0
|
|
21
|
+
Description-Content-Type: text/markdown
|
|
22
|
+
|
|
23
|
+
# gams-frog
|
|
24
|
+
|
|
25
|
+
CLI tool that generates frontends for GAMS5 projects.
|
|
26
|
+
Supplies a development workflow for GAMS5-based web projects.
|
|
27
|
+
|
|
28
|
+
Meant as replacement for the gams3 "gamsdev" development workflow.
|
|
29
|
+
|
|
30
|
+
## Quickstart
|
|
31
|
+
|
|
32
|
+
1. Setup project files for gams-frog
|
|
33
|
+
|
|
34
|
+
2. Install gams-frog itself
|
|
35
|
+
|
|
36
|
+
```sh
|
|
37
|
+
|
|
38
|
+
# 1. install uv
|
|
39
|
+
# mac might need brew to install uv
|
|
40
|
+
|
|
41
|
+
# 2. install gams_frog via
|
|
42
|
+
# optionally specifiy version tag
|
|
43
|
+
uv tool install gams_frog
|
|
44
|
+
|
|
45
|
+
# verify installation via
|
|
46
|
+
frog --version
|
|
47
|
+
|
|
48
|
+
# 3. use the gams_frog
|
|
49
|
+
cd ./my/working/directory
|
|
50
|
+
frog dev # will use the gams_frog.toml from the current working dir
|
|
51
|
+
# alternatively specifiy a path
|
|
52
|
+
frog dev "C:\path\to\project"
|
|
53
|
+
# check for basic commands
|
|
54
|
+
frog
|
|
55
|
+
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Basic usage
|
|
59
|
+
|
|
60
|
+
1. Have a running GAM5-API (OR external)
|
|
61
|
+
2. Clone or init project files
|
|
62
|
+
3. UV setup (install via pypi or clone via git)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
```sh
|
|
66
|
+
# 01. Setup project files from templates: https://zimlab.uni-graz.at/gams5/projects/project_template/gams-www
|
|
67
|
+
# 01b. Install uv (python package)
|
|
68
|
+
|
|
69
|
+
# 02a. Install via pypi
|
|
70
|
+
# 02a. uv install / pip install
|
|
71
|
+
|
|
72
|
+
# 02b. Clone gams_frog
|
|
73
|
+
# 02b. uv sync (uv procedure)
|
|
74
|
+
# 02b. Start virtual environment (venv)
|
|
75
|
+
|
|
76
|
+
# 03. Configure gams_frog via config file (gams_frog.toml) in template project folder
|
|
77
|
+
|
|
78
|
+
# (point to project folder with config file)
|
|
79
|
+
frog dev "C:\path\to\project"
|
|
80
|
+
|
|
81
|
+
# for production use
|
|
82
|
+
frog build "C:\path\to\project"
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Staging
|
|
87
|
+
|
|
88
|
+
```sh
|
|
89
|
+
frog stage "/path/to/project"
|
|
90
|
+
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
### Production
|
|
95
|
+
|
|
96
|
+
```sh
|
|
97
|
+
# use build command to generate the production files
|
|
98
|
+
frog build "/path/to/project"
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
### Deployment
|
|
104
|
+
|
|
105
|
+
- use the -d flag to deploy to staging or production environment
|
|
106
|
+
|
|
107
|
+
```sh
|
|
108
|
+
# staging deployment
|
|
109
|
+
frog stage "/path/to/project" -d
|
|
110
|
+
|
|
111
|
+
# production deployment
|
|
112
|
+
frog build "/path/to/project" -d
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
## Development
|
|
119
|
+
|
|
120
|
+
### Release
|
|
121
|
+
|
|
122
|
+
1. Increment version in pyproject.toml in feature branch (merging into develop):
|
|
123
|
+
- make sure version follow vd.d.d pattern
|
|
124
|
+
2. Merge changes to develop -> main
|
|
125
|
+
3. Create release on the gitlab webclient (from main branch) with new git tag that must be the same as in the pyproject.toml!
|
|
126
|
+
- e.g. v0.1.1
|
|
127
|
+
- create the release from the main branch!
|
|
128
|
+
- gitlab will autodeploy the new version to pypi
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
# gams-frog
|
|
2
|
+
|
|
3
|
+
CLI tool that generates frontends for GAMS5 projects.
|
|
4
|
+
Supplies a development workflow for GAMS5-based web projects.
|
|
5
|
+
|
|
6
|
+
Meant as replacement for the gams3 "gamsdev" development workflow.
|
|
7
|
+
|
|
8
|
+
## Quickstart
|
|
9
|
+
|
|
10
|
+
1. Setup project files for gams-frog
|
|
11
|
+
|
|
12
|
+
2. Install gams-frog itself
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
|
|
16
|
+
# 1. install uv
|
|
17
|
+
# mac might need brew to install uv
|
|
18
|
+
|
|
19
|
+
# 2. install gams_frog via
|
|
20
|
+
# optionally specifiy version tag
|
|
21
|
+
uv tool install gams_frog
|
|
22
|
+
|
|
23
|
+
# verify installation via
|
|
24
|
+
frog --version
|
|
25
|
+
|
|
26
|
+
# 3. use the gams_frog
|
|
27
|
+
cd ./my/working/directory
|
|
28
|
+
frog dev # will use the gams_frog.toml from the current working dir
|
|
29
|
+
# alternatively specifiy a path
|
|
30
|
+
frog dev "C:\path\to\project"
|
|
31
|
+
# check for basic commands
|
|
32
|
+
frog
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Basic usage
|
|
37
|
+
|
|
38
|
+
1. Have a running GAM5-API (OR external)
|
|
39
|
+
2. Clone or init project files
|
|
40
|
+
3. UV setup (install via pypi or clone via git)
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
```sh
|
|
44
|
+
# 01. Setup project files from templates: https://zimlab.uni-graz.at/gams5/projects/project_template/gams-www
|
|
45
|
+
# 01b. Install uv (python package)
|
|
46
|
+
|
|
47
|
+
# 02a. Install via pypi
|
|
48
|
+
# 02a. uv install / pip install
|
|
49
|
+
|
|
50
|
+
# 02b. Clone gams_frog
|
|
51
|
+
# 02b. uv sync (uv procedure)
|
|
52
|
+
# 02b. Start virtual environment (venv)
|
|
53
|
+
|
|
54
|
+
# 03. Configure gams_frog via config file (gams_frog.toml) in template project folder
|
|
55
|
+
|
|
56
|
+
# (point to project folder with config file)
|
|
57
|
+
frog dev "C:\path\to\project"
|
|
58
|
+
|
|
59
|
+
# for production use
|
|
60
|
+
frog build "C:\path\to\project"
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Staging
|
|
65
|
+
|
|
66
|
+
```sh
|
|
67
|
+
frog stage "/path/to/project"
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
### Production
|
|
73
|
+
|
|
74
|
+
```sh
|
|
75
|
+
# use build command to generate the production files
|
|
76
|
+
frog build "/path/to/project"
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
### Deployment
|
|
82
|
+
|
|
83
|
+
- use the -d flag to deploy to staging or production environment
|
|
84
|
+
|
|
85
|
+
```sh
|
|
86
|
+
# staging deployment
|
|
87
|
+
frog stage "/path/to/project" -d
|
|
88
|
+
|
|
89
|
+
# production deployment
|
|
90
|
+
frog build "/path/to/project" -d
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
## Development
|
|
97
|
+
|
|
98
|
+
### Release
|
|
99
|
+
|
|
100
|
+
1. Increment version in pyproject.toml in feature branch (merging into develop):
|
|
101
|
+
- make sure version follow vd.d.d pattern
|
|
102
|
+
2. Merge changes to develop -> main
|
|
103
|
+
3. Create release on the gitlab webclient (from main branch) with new git tag that must be the same as in the pyproject.toml!
|
|
104
|
+
- e.g. v0.1.1
|
|
105
|
+
- create the release from the main branch!
|
|
106
|
+
- gitlab will autodeploy the new version to pypi
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "gams-frog"
|
|
3
|
+
version = "v0.3.0"
|
|
4
|
+
description = "CLI tool for frontend generation for GAMS5 projects"
|
|
5
|
+
authors = [
|
|
6
|
+
{ name = "Sebastian David Schiller-Stoff", email = "sebastian.stoff@uni-graz.at" }
|
|
7
|
+
]
|
|
8
|
+
license = { text = "MIT" }
|
|
9
|
+
dependencies = [
|
|
10
|
+
"jinja2==3.1.6",
|
|
11
|
+
"click>=8.3.1",
|
|
12
|
+
"watchdog>=6.0.0",
|
|
13
|
+
"aiohttp>=3.13.3",
|
|
14
|
+
"requests>=2.32.4"
|
|
15
|
+
]
|
|
16
|
+
readme = "README.md"
|
|
17
|
+
requires-python = ">= 3.12"
|
|
18
|
+
keywords = ["gams", "static-site-generator", "digital-humanities", "jinja2"]
|
|
19
|
+
classifiers = [
|
|
20
|
+
"Development Status :: 4 - Beta",
|
|
21
|
+
"Environment :: Console",
|
|
22
|
+
"Intended Audience :: Developers",
|
|
23
|
+
"Topic :: Internet :: WWW/HTTP :: Site Management",
|
|
24
|
+
"Programming Language :: Python :: 3.12",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
[project.urls]
|
|
28
|
+
Repository = "https://zimlab.uni-graz.at/gams5/production/postprocessing/gams-frog"
|
|
29
|
+
|
|
30
|
+
[build-system]
|
|
31
|
+
requires = ["hatchling"]
|
|
32
|
+
build-backend = "hatchling.build"
|
|
33
|
+
|
|
34
|
+
[tool.hatch.metadata]
|
|
35
|
+
allow-direct-references = true
|
|
36
|
+
|
|
37
|
+
[tool.hatch.build.targets.wheel]
|
|
38
|
+
packages = ["src/gams_frog"]
|
|
39
|
+
|
|
40
|
+
[dependency-groups]
|
|
41
|
+
dev = [
|
|
42
|
+
"pytest>=8.4.1",
|
|
43
|
+
"ruff>=0.14.0"
|
|
44
|
+
]
|
|
45
|
+
|
|
46
|
+
[project.scripts]
|
|
47
|
+
frog = "gams_frog.cli:cli"
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
import click
|
|
5
|
+
import multiprocessing
|
|
6
|
+
|
|
7
|
+
from importlib.metadata import version, PackageNotFoundError
|
|
8
|
+
# makes sure that the version is set correctly
|
|
9
|
+
try:
|
|
10
|
+
__version__ = version("gams_frog-tool")
|
|
11
|
+
except PackageNotFoundError:
|
|
12
|
+
__version__ = "dev"
|
|
13
|
+
|
|
14
|
+
from gams_frog.deploy.GamsAuthClient import GamsAuthClient
|
|
15
|
+
from gams_frog.ssr.watch.ApplicationViewFileEventController import ApplicationViewFileEventController
|
|
16
|
+
from gams_frog.ssr.init.ApplicationContext import ApplicationContext
|
|
17
|
+
from gams_frog.ssr.load.ApplicationDataLoader import ApplicationDataLoader
|
|
18
|
+
from gams_frog.ssr.watch.ApplicationViewFileWatcher import ApplicationViewFileWatcher
|
|
19
|
+
from gams_frog.ssr.watch.ApplicationWebServer import ApplicationWebServer
|
|
20
|
+
from gams_frog.ssr.init.AppInitializer import AppInitializer
|
|
21
|
+
from gams_frog.validation.JinjaTemplateValidator import JinjaTemplateValidator
|
|
22
|
+
from gams_frog.validation.StaticFileValidator import StaticFileValidator
|
|
23
|
+
|
|
24
|
+
# global application context
|
|
25
|
+
app_context = ApplicationContext()
|
|
26
|
+
|
|
27
|
+
def run_validation_or_exit(context: ApplicationContext):
|
|
28
|
+
# 1. Validate Templates (AST)
|
|
29
|
+
template_validator = JinjaTemplateValidator(context)
|
|
30
|
+
templates_ok = template_validator.validate()
|
|
31
|
+
|
|
32
|
+
# 2. Validate Static Files (Regex)
|
|
33
|
+
static_validator = StaticFileValidator(context)
|
|
34
|
+
static_ok = static_validator.validate()
|
|
35
|
+
|
|
36
|
+
if not (templates_ok and static_ok):
|
|
37
|
+
logging.error("Build aborted due to quality gate violations.")
|
|
38
|
+
sys.exit(1)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
def run_deploy(context: ApplicationContext, username: str | None, password: str | None):
|
|
42
|
+
"""
|
|
43
|
+
Performs authentication and deployment to the GAMS5 API.
|
|
44
|
+
|
|
45
|
+
:param context: The application context
|
|
46
|
+
:param username: GAMS API username (prompted if not provided)
|
|
47
|
+
:param password: GAMS API password (prompted if not provided)
|
|
48
|
+
"""
|
|
49
|
+
from gams_frog.deploy.DeployService import DeployService
|
|
50
|
+
|
|
51
|
+
mode = context.get_config().mode
|
|
52
|
+
target_host = context.get_config().gams_host
|
|
53
|
+
|
|
54
|
+
# Safety confirmation for production deployments
|
|
55
|
+
if mode == "build":
|
|
56
|
+
click.echo("\n*** PRODUCTION DEPLOYMENT ***")
|
|
57
|
+
click.echo(f"Target: {target_host}")
|
|
58
|
+
click.echo(f"Project: {context.get_config().project}")
|
|
59
|
+
if not click.confirm("Deploy to PRODUCTION environment?", default=False):
|
|
60
|
+
click.echo("Deployment cancelled.")
|
|
61
|
+
return
|
|
62
|
+
|
|
63
|
+
# Prompt for credentials if not provided via options
|
|
64
|
+
if not username:
|
|
65
|
+
username = click.prompt("GAMS API username")
|
|
66
|
+
if not password:
|
|
67
|
+
password = click.prompt("GAMS API password", hide_input=True)
|
|
68
|
+
|
|
69
|
+
# Authenticate
|
|
70
|
+
logging.info(f"Authenticating with GAMS API at {target_host}...")
|
|
71
|
+
auth_gams_client = GamsAuthClient(target_host)
|
|
72
|
+
try:
|
|
73
|
+
from gams_frog.deploy.AuthorizationService import AuthorizationService
|
|
74
|
+
# TODO using a separte client seems weird
|
|
75
|
+
auth_service = AuthorizationService(auth_gams_client)
|
|
76
|
+
auth_service.login(username=username, password=password)
|
|
77
|
+
except PermissionError as e:
|
|
78
|
+
logging.error(f"Authentication failed: {e}")
|
|
79
|
+
sys.exit(1)
|
|
80
|
+
except Exception as e:
|
|
81
|
+
logging.error(f"Authentication error: {e}")
|
|
82
|
+
sys.exit(1)
|
|
83
|
+
|
|
84
|
+
# Deploy
|
|
85
|
+
try:
|
|
86
|
+
deploy_service = DeployService(context, auth_gams_client)
|
|
87
|
+
result = deploy_service.deploy()
|
|
88
|
+
click.echo("\nDeployment successful!")
|
|
89
|
+
click.echo(f" Project: {result.get('projectAbbr', 'N/A')}")
|
|
90
|
+
click.echo(f" Files: {result.get('fileCount', 'N/A')}")
|
|
91
|
+
click.echo(f" Total size: {result.get('totalSize', 'N/A')} bytes")
|
|
92
|
+
click.echo(f" Deployed at: {result.get('deployedAt', 'N/A')}")
|
|
93
|
+
except (FileNotFoundError, ValueError) as e:
|
|
94
|
+
logging.error(f"Deployment failed: {e}")
|
|
95
|
+
sys.exit(1)
|
|
96
|
+
except (ConnectionError, PermissionError) as e:
|
|
97
|
+
logging.error(f"Deployment failed: {e}")
|
|
98
|
+
sys.exit(1)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
@click.group()
|
|
102
|
+
@click.version_option(version=version("gams_frog"), prog_name="gams_frog")
|
|
103
|
+
@click.option("--log", "-l", default="INFO", help="log level, default is INFO")
|
|
104
|
+
def cli(log: str):
|
|
105
|
+
"""
|
|
106
|
+
Init command / start routine of application
|
|
107
|
+
Sets up the application context for the entire application.
|
|
108
|
+
"""
|
|
109
|
+
logging.basicConfig( encoding='utf-8', level=logging.getLevelName(log))
|
|
110
|
+
|
|
111
|
+
@cli.command(name="stage", help="Builds output files once with staging configuration.")
|
|
112
|
+
@click.argument("directory", default=".", required=False)
|
|
113
|
+
@click.option("--deploy", "-d", is_flag=True, default=False, help="Deploy the built files to the staging GAMS API after build.")
|
|
114
|
+
@click.option("--username", "-u", default=None, help="GAMS API username for deployment.")
|
|
115
|
+
@click.option("--password", "-p", default=None, help="GAMS API password for deployment.")
|
|
116
|
+
def stage(directory: str, deploy: bool, username: str, password: str):
|
|
117
|
+
"""
|
|
118
|
+
Builds the static site generator output files with staging config.
|
|
119
|
+
Use --deploy to upload the result to the staging GAMS API.
|
|
120
|
+
"""
|
|
121
|
+
|
|
122
|
+
# setting up the application context
|
|
123
|
+
(AppInitializer(app_context)
|
|
124
|
+
.configure(
|
|
125
|
+
directory=directory,
|
|
126
|
+
mode="stage"
|
|
127
|
+
)
|
|
128
|
+
.init_context_beans()
|
|
129
|
+
.setup()
|
|
130
|
+
)
|
|
131
|
+
|
|
132
|
+
# validate template files first
|
|
133
|
+
run_validation_or_exit(app_context)
|
|
134
|
+
|
|
135
|
+
# encapsulates loading of project data and digital objects
|
|
136
|
+
(ApplicationDataLoader(app_context)
|
|
137
|
+
.load())
|
|
138
|
+
|
|
139
|
+
# render all views (and handle related files etc.)
|
|
140
|
+
(ApplicationViewFileEventController(app_context)
|
|
141
|
+
.render_views())
|
|
142
|
+
|
|
143
|
+
# deploy if requested
|
|
144
|
+
if deploy:
|
|
145
|
+
run_deploy(app_context, username, password)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
@cli.command(name="build", help="Builds production output files.")
|
|
149
|
+
@click.argument("directory", default=".", required=False)
|
|
150
|
+
@click.option("--deploy", "-d", is_flag=True, default=False, help="Deploy the built files to the production GAMS API after build.")
|
|
151
|
+
@click.option("--username", "-u", default=None, help="GAMS API username for deployment.")
|
|
152
|
+
@click.option("--password", "-p", default=None, help="GAMS API password for deployment.")
|
|
153
|
+
def build(directory: str, deploy: bool, username: str, password: str):
|
|
154
|
+
"""
|
|
155
|
+
Builds the static site generator production output files.
|
|
156
|
+
Use --deploy to upload the result to the production GAMS API.
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
# setting up the application context
|
|
160
|
+
(AppInitializer(app_context)
|
|
161
|
+
.configure(
|
|
162
|
+
directory=directory,
|
|
163
|
+
mode="build"
|
|
164
|
+
)
|
|
165
|
+
.init_context_beans()
|
|
166
|
+
.setup()
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
# validate template files first
|
|
170
|
+
run_validation_or_exit(app_context)
|
|
171
|
+
|
|
172
|
+
# encapsulates loading of project data and digital objects
|
|
173
|
+
(ApplicationDataLoader(app_context)
|
|
174
|
+
.load())
|
|
175
|
+
|
|
176
|
+
# render all views (and handle related files etc.)
|
|
177
|
+
(ApplicationViewFileEventController(app_context)
|
|
178
|
+
.render_views())
|
|
179
|
+
|
|
180
|
+
# deploy if requested
|
|
181
|
+
if deploy:
|
|
182
|
+
run_deploy(app_context, username, password)
|
|
183
|
+
|
|
184
|
+
|
|
185
|
+
@cli.command(name="dev", help="Starts the development process of the gams_frog tool.")
|
|
186
|
+
@click.argument("directory", default=".", required=False)
|
|
187
|
+
@click.option("--port", "-p", default=18090, help="The port to run the development server on")
|
|
188
|
+
def dev(directory: str, port: int):
|
|
189
|
+
"""
|
|
190
|
+
Starts the static site generator (web server with rendering of views and initial data loading etc.)
|
|
191
|
+
"""
|
|
192
|
+
|
|
193
|
+
# setting up the application context
|
|
194
|
+
(AppInitializer(app_context)
|
|
195
|
+
.configure(
|
|
196
|
+
directory=directory,
|
|
197
|
+
mode="dev"
|
|
198
|
+
)
|
|
199
|
+
.init_context_beans()
|
|
200
|
+
.setup()
|
|
201
|
+
)
|
|
202
|
+
|
|
203
|
+
# first run validation
|
|
204
|
+
run_validation_or_exit(app_context)
|
|
205
|
+
|
|
206
|
+
# encapsulates loading of project data and digital objects
|
|
207
|
+
(ApplicationDataLoader(app_context)
|
|
208
|
+
.load())
|
|
209
|
+
|
|
210
|
+
web_dir = app_context.get_config().public_dir
|
|
211
|
+
dev_server_process = multiprocessing.Process(target=ApplicationWebServer.start, args=(web_dir, port,))
|
|
212
|
+
|
|
213
|
+
try:
|
|
214
|
+
logging.info(f"*** Starting web server at port {port}")
|
|
215
|
+
dev_server_process.start()
|
|
216
|
+
logging.info("*** Starting view file watcher now")
|
|
217
|
+
ApplicationViewFileWatcher.start(
|
|
218
|
+
app_context
|
|
219
|
+
)
|
|
220
|
+
dev_server_process.join()
|
|
221
|
+
except KeyboardInterrupt:
|
|
222
|
+
logging.info("Keyboard interrupt received. Stopping processes")
|
|
223
|
+
dev_server_process.terminate()
|
|
224
|
+
dev_server_process.join()
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
cli.add_command(dev)
|
|
228
|
+
cli.add_command(build)
|
|
229
|
+
cli.add_command(stage)
|