Compare commits
21 Commits
build/migr
...
f9e630e49b
| Author | SHA1 | Date | |
|---|---|---|---|
| f9e630e49b | |||
| 6872348375 | |||
| 7c98d16cc2 | |||
| 06ea0246f5 | |||
| cde27d37e3 | |||
| 3709a42e64 | |||
| 7b09a72d5c | |||
|
f3f521efe2
|
|||
|
feb7a71816
|
|||
|
e15f02be05
|
|||
|
5031799072
|
|||
|
26fac14802
|
|||
|
75694f9200
|
|||
|
522c14793a
|
|||
|
9a074f17d8
|
|||
|
6ec1af2cf7
|
|||
|
ff911bc8bc
|
|||
|
446e5fbc04
|
|||
|
04c46f1e98
|
|||
|
2786f39b9b
|
|||
|
ad479fe0d7
|
121
.github/workflows/release.yaml
vendored
121
.github/workflows/release.yaml
vendored
@@ -1,121 +0,0 @@
|
|||||||
name: Bump version
|
|
||||||
|
|
||||||
on:
|
|
||||||
workflow_dispatch:
|
|
||||||
inputs:
|
|
||||||
short_description:
|
|
||||||
type: string
|
|
||||||
description: 'Short description of the release'
|
|
||||||
required: false
|
|
||||||
auto_bump:
|
|
||||||
type: boolean
|
|
||||||
description: 'Auto bump version?'
|
|
||||||
required: true
|
|
||||||
bump_type:
|
|
||||||
type: choice
|
|
||||||
description: 'Bump type'
|
|
||||||
required: true
|
|
||||||
options:
|
|
||||||
- 'major'
|
|
||||||
- 'minor'
|
|
||||||
- 'patch'
|
|
||||||
- 'prerelease'
|
|
||||||
as_pre_release:
|
|
||||||
type: boolean
|
|
||||||
description: 'As pre-release?'
|
|
||||||
required: true
|
|
||||||
prerelease_type:
|
|
||||||
type: choice
|
|
||||||
description: 'Pre-release label'
|
|
||||||
required: true
|
|
||||||
options:
|
|
||||||
- 'dev'
|
|
||||||
- 'alpha'
|
|
||||||
- 'beta'
|
|
||||||
- 'rc'
|
|
||||||
- 'post'
|
|
||||||
jobs:
|
|
||||||
bump_version:
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
name: Bump version and create release
|
|
||||||
steps:
|
|
||||||
- name: 🔀 checkout
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
fetch-depth: 0
|
|
||||||
token: "${{ secrets.GITHUB_TOKEN }}"
|
|
||||||
submodules: 'recursive'
|
|
||||||
|
|
||||||
- name: 📦 install uv
|
|
||||||
uses: astral-sh/setup-uv@v5
|
|
||||||
|
|
||||||
- name: 🐍 python
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version-file: "pyproject.toml"
|
|
||||||
|
|
||||||
- name: 📦 sync depedencies
|
|
||||||
run: |
|
|
||||||
uv sync
|
|
||||||
uv sync --group bump
|
|
||||||
|
|
||||||
- name: configure git
|
|
||||||
run: |
|
|
||||||
git config --global user.name "github-actions[bot]"
|
|
||||||
git config --global user.email "github-actions[bot]@users.noreply.github.com"
|
|
||||||
|
|
||||||
- name: 📦 bump version (auto)
|
|
||||||
if: ${{ github.event.inputs.auto_bump == 'true' }}
|
|
||||||
run: |
|
|
||||||
if [ "${{ github.event.inputs.as_pre_release }}" == "true" ]; then
|
|
||||||
uv run semantic-release version --no-changelog --no-commit --no-push --as-prerelease --prerelease-token ${{ github.event.inputs.prerelease_type }}
|
|
||||||
else
|
|
||||||
uv run semantic-release version --no-changelog --no-commit --no-push
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: 📦 bump version (manual)
|
|
||||||
if: ${{ github.event.inputs.auto_bump == 'false' }}
|
|
||||||
run: |
|
|
||||||
if [ "${{ github.event.inputs.as_pre_release }}" == "true" ]; then
|
|
||||||
uv run semantic-release version --no-changelog --no-commit --no-push --${{ github.event.inputs.bump_type }} --as-prerelease --prerelease-token ${{ github.event.inputs.prerelease_type }}
|
|
||||||
else
|
|
||||||
uv run semantic-release version --no-changelog --no-commit --no-push --${{ github.event.inputs.bump_type }}
|
|
||||||
fi
|
|
||||||
|
|
||||||
- name: 📦 get new version
|
|
||||||
id: get_version
|
|
||||||
run: echo "BUMPED_VERSION=$(cat pyproject.toml | grep -e "^version = " | cut -d '"' -f 2)" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: 📝 create changelog
|
|
||||||
run: |
|
|
||||||
uv run git-cliff -s header -l > release_body.md
|
|
||||||
echo "Changes:" && cat release_body.md
|
|
||||||
uv run git-cliff > CHANGELOG.md
|
|
||||||
|
|
||||||
- name: 📤 push changes
|
|
||||||
run: |
|
|
||||||
git add CHANGELOG.md pyproject.toml src/*/__init__.py
|
|
||||||
git commit -m "chore(release): ${{ steps.get_version.outputs.BUMPED_VERSION }}"
|
|
||||||
git push origin main
|
|
||||||
|
|
||||||
- name: create release
|
|
||||||
uses: softprops/action-gh-release@v2
|
|
||||||
with:
|
|
||||||
name: ${{ github.event.repository.name }} ${{ steps.get_version.outputs.BUMPED_VERSION }} - ${{ github.event.inputs.short_description }}
|
|
||||||
tag_name: ${{ steps.get_version.outputs.BUMPED_VERSION }}
|
|
||||||
body_path: release_body.md
|
|
||||||
prerelease: ${{ github.event.inputs.as_pre_release }}
|
|
||||||
discussion_category_name: 'Announcements'
|
|
||||||
|
|
||||||
- name: 🧹 cleanup
|
|
||||||
run: |
|
|
||||||
rm release_body.md
|
|
||||||
|
|
||||||
- name: 📤 merge into develop
|
|
||||||
run: |
|
|
||||||
git checkout develop
|
|
||||||
git merge main
|
|
||||||
git push origin develop
|
|
||||||
|
|
||||||
- name: ✅ done
|
|
||||||
run: echo "done"
|
|
||||||
49
.gitignore
vendored
49
.gitignore
vendored
@@ -1,47 +1,6 @@
|
|||||||
# VSCode stuff
|
.py[cod]
|
||||||
.vscode/*
|
|
||||||
!.vscode/settings.json
|
|
||||||
!.vscode/tasks.json
|
|
||||||
!.vscode/launch.json
|
|
||||||
!.vscode/extensions.json
|
|
||||||
!.vscode/*.code-snippets
|
|
||||||
|
|
||||||
# Byte-compiled / optimized / DLL files
|
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.py[cod]
|
.mypy_cache/
|
||||||
*$py.class
|
|
||||||
|
|
||||||
# Environments
|
|
||||||
.env
|
|
||||||
.venv
|
|
||||||
env/
|
|
||||||
venv/
|
|
||||||
ENV/
|
|
||||||
env.bak/
|
|
||||||
venv.bak/
|
|
||||||
|
|
||||||
# PDM
|
|
||||||
.pdm*
|
|
||||||
!pdm.lock
|
|
||||||
|
|
||||||
# uv
|
|
||||||
.python-version
|
|
||||||
!uv.lock
|
|
||||||
|
|
||||||
# Distribution / packaging
|
|
||||||
dist/
|
|
||||||
build/
|
|
||||||
/*cache/
|
|
||||||
|
|
||||||
# Tests
|
|
||||||
.pytest_cache/
|
.pytest_cache/
|
||||||
.coverage
|
.ruff_cache/
|
||||||
.htmlcov/
|
.pdm-python
|
||||||
|
|
||||||
# Log files
|
|
||||||
logs/
|
|
||||||
*.log
|
|
||||||
|
|
||||||
# Sphinx
|
|
||||||
docs/_build/
|
|
||||||
docs/ref/modules/
|
|
||||||
|
|||||||
22
.vscode/launch.json
vendored
Normal file
22
.vscode/launch.json
vendored
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
{
|
||||||
|
// Use IntelliSense to learn about possible attributes.
|
||||||
|
// Hover to view descriptions of existing attributes.
|
||||||
|
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
|
||||||
|
"version": "0.2.0",
|
||||||
|
"configurations": [
|
||||||
|
{
|
||||||
|
"name": "Launch Flask",
|
||||||
|
"type": "debugpy",
|
||||||
|
"request": "launch",
|
||||||
|
"module": "flask",
|
||||||
|
"env": {
|
||||||
|
"FLASK_APP": "judas_server/web/web_server.py",
|
||||||
|
},
|
||||||
|
"args": [
|
||||||
|
"run",
|
||||||
|
],
|
||||||
|
"console": "internalConsole",
|
||||||
|
"justMyCode": true,
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,134 +0,0 @@
|
|||||||
|
|
||||||
# Contributor Covenant Code of Conduct
|
|
||||||
|
|
||||||
## Our Pledge
|
|
||||||
|
|
||||||
We as members, contributors, and leaders pledge to make participation in our
|
|
||||||
community a harassment-free experience for everyone, regardless of age, body
|
|
||||||
size, visible or invisible disability, ethnicity, sex characteristics, gender
|
|
||||||
identity and expression, level of experience, education, socio-economic status,
|
|
||||||
nationality, personal appearance, race, caste, color, religion, or sexual
|
|
||||||
identity and orientation.
|
|
||||||
|
|
||||||
We pledge to act and interact in ways that contribute to an open, welcoming,
|
|
||||||
diverse, inclusive, and healthy community.
|
|
||||||
|
|
||||||
## Our Standards
|
|
||||||
|
|
||||||
Examples of behavior that contributes to a positive environment for our
|
|
||||||
community include:
|
|
||||||
|
|
||||||
* Demonstrating empathy and kindness toward other people
|
|
||||||
* Being respectful of differing opinions, viewpoints, and experiences
|
|
||||||
* Giving and gracefully accepting constructive feedback
|
|
||||||
* Accepting responsibility and apologizing to those affected by our mistakes,
|
|
||||||
and learning from the experience
|
|
||||||
* Focusing on what is best not just for us as individuals, but for the overall
|
|
||||||
community
|
|
||||||
|
|
||||||
Examples of unacceptable behavior include:
|
|
||||||
|
|
||||||
* The use of sexualized language or imagery, and sexual attention or advances of
|
|
||||||
any kind
|
|
||||||
* Trolling, insulting or derogatory comments, and personal or political attacks
|
|
||||||
* Public or private harassment
|
|
||||||
* Publishing others' private information, such as a physical or email address,
|
|
||||||
without their explicit permission
|
|
||||||
* Other conduct which could reasonably be considered inappropriate in a
|
|
||||||
professional setting
|
|
||||||
|
|
||||||
## Enforcement Responsibilities
|
|
||||||
|
|
||||||
Community leaders are responsible for clarifying and enforcing our standards of
|
|
||||||
acceptable behavior and will take appropriate and fair corrective action in
|
|
||||||
response to any behavior that they deem inappropriate, threatening, offensive,
|
|
||||||
or harmful.
|
|
||||||
|
|
||||||
Community leaders have the right and responsibility to remove, edit, or reject
|
|
||||||
comments, commits, code, wiki edits, issues, and other contributions that are
|
|
||||||
not aligned to this Code of Conduct, and will communicate reasons for moderation
|
|
||||||
decisions when appropriate.
|
|
||||||
|
|
||||||
## Scope
|
|
||||||
|
|
||||||
This Code of Conduct applies within all community spaces, and also applies when
|
|
||||||
an individual is officially representing the community in public spaces.
|
|
||||||
Examples of representing our community include using an official e-mail address,
|
|
||||||
posting via an official social media account, or acting as an appointed
|
|
||||||
representative at an online or offline event.
|
|
||||||
|
|
||||||
## Enforcement
|
|
||||||
|
|
||||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
|
||||||
reported to the community leaders responsible for enforcement at
|
|
||||||
[INSERT CONTACT METHOD].
|
|
||||||
All complaints will be reviewed and investigated promptly and fairly.
|
|
||||||
|
|
||||||
All community leaders are obligated to respect the privacy and security of the
|
|
||||||
reporter of any incident.
|
|
||||||
|
|
||||||
## Enforcement Guidelines
|
|
||||||
|
|
||||||
Community leaders will follow these Community Impact Guidelines in determining
|
|
||||||
the consequences for any action they deem in violation of this Code of Conduct:
|
|
||||||
|
|
||||||
### 1. Correction
|
|
||||||
|
|
||||||
**Community Impact**: Use of inappropriate language or other behavior deemed
|
|
||||||
unprofessional or unwelcome in the community.
|
|
||||||
|
|
||||||
**Consequence**: A private, written warning from community leaders, providing
|
|
||||||
clarity around the nature of the violation and an explanation of why the
|
|
||||||
behavior was inappropriate. A public apology may be requested.
|
|
||||||
|
|
||||||
### 2. Warning
|
|
||||||
|
|
||||||
**Community Impact**: A violation through a single incident or series of
|
|
||||||
actions.
|
|
||||||
|
|
||||||
**Consequence**: A warning with consequences for continued behavior. No
|
|
||||||
interaction with the people involved, including unsolicited interaction with
|
|
||||||
those enforcing the Code of Conduct, for a specified period of time. This
|
|
||||||
includes avoiding interactions in community spaces as well as external channels
|
|
||||||
like social media. Violating these terms may lead to a temporary or permanent
|
|
||||||
ban.
|
|
||||||
|
|
||||||
### 3. Temporary Ban
|
|
||||||
|
|
||||||
**Community Impact**: A serious violation of community standards, including
|
|
||||||
sustained inappropriate behavior.
|
|
||||||
|
|
||||||
**Consequence**: A temporary ban from any sort of interaction or public
|
|
||||||
communication with the community for a specified period of time. No public or
|
|
||||||
private interaction with the people involved, including unsolicited interaction
|
|
||||||
with those enforcing the Code of Conduct, is allowed during this period.
|
|
||||||
Violating these terms may lead to a permanent ban.
|
|
||||||
|
|
||||||
### 4. Permanent Ban
|
|
||||||
|
|
||||||
**Community Impact**: Demonstrating a pattern of violation of community
|
|
||||||
standards, including sustained inappropriate behavior, harassment of an
|
|
||||||
individual, or aggression toward or disparagement of classes of individuals.
|
|
||||||
|
|
||||||
**Consequence**: A permanent ban from any sort of public interaction within the
|
|
||||||
community.
|
|
||||||
|
|
||||||
## Attribution
|
|
||||||
|
|
||||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
|
||||||
version 2.1, available at
|
|
||||||
[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1].
|
|
||||||
|
|
||||||
Community Impact Guidelines were inspired by
|
|
||||||
[Mozilla's code of conduct enforcement ladder][Mozilla CoC].
|
|
||||||
|
|
||||||
For answers to common questions about this code of conduct, see the FAQ at
|
|
||||||
[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at
|
|
||||||
[https://www.contributor-covenant.org/translations][translations].
|
|
||||||
|
|
||||||
[homepage]: https://www.contributor-covenant.org
|
|
||||||
[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html
|
|
||||||
[Mozilla CoC]: https://github.com/mozilla/diversity
|
|
||||||
[FAQ]: https://www.contributor-covenant.org/faq
|
|
||||||
[translations]: https://www.contributor-covenant.org/translations
|
|
||||||
|
|
||||||
83
cliff.toml
83
cliff.toml
@@ -1,83 +0,0 @@
|
|||||||
# git-cliff ~ default configuration file
|
|
||||||
# https://git-cliff.org/docs/configuration
|
|
||||||
#
|
|
||||||
# Lines starting with "#" are comments.
|
|
||||||
# Configuration options are organized into tables and keys.
|
|
||||||
# See documentation for more information on available options.
|
|
||||||
|
|
||||||
[changelog]
|
|
||||||
# changelog header
|
|
||||||
header = """
|
|
||||||
# Changelog\n
|
|
||||||
All notable changes to this project will be documented in this file.\n
|
|
||||||
"""
|
|
||||||
# template for the changelog body
|
|
||||||
# https://keats.github.io/tera/docs/#introduction
|
|
||||||
body = """
|
|
||||||
{% if version %}\
|
|
||||||
## [{{ version | trim_start_matches(pat="v") }}] - {{ timestamp | date(format="%Y-%m-%d") }}
|
|
||||||
{% else %}\
|
|
||||||
## [unreleased]
|
|
||||||
{% endif %}\
|
|
||||||
{% for group, commits in commits | group_by(attribute="group") %}
|
|
||||||
### {{ group | upper_first }}
|
|
||||||
{% for commit in commits %}
|
|
||||||
- [`{{ commit.id|truncate(length=7, end="") }}`](<REPO>/commit/{{ commit.id }}) {% if commit.scope %}**{{ commit.scope }}**: {% endif %}{% if commit.breaking %}[**breaking**] {% endif %}{{ commit.message}}\
|
|
||||||
{% endfor %}
|
|
||||||
{% endfor %}\n
|
|
||||||
"""
|
|
||||||
# remove the leading and trailing whitespace from the template
|
|
||||||
trim = true
|
|
||||||
# changelog footer
|
|
||||||
footer = """
|
|
||||||
<!-- generated by git-cliff -->
|
|
||||||
"""
|
|
||||||
# postprocessors
|
|
||||||
postprocessors = [
|
|
||||||
{ pattern = '<REPO>', replace = "https://github.com/pufereq/template-repo" }, # replace repository URL
|
|
||||||
]
|
|
||||||
[git]
|
|
||||||
# parse the commits based on https://www.conventionalcommits.org
|
|
||||||
conventional_commits = true
|
|
||||||
# filter out the commits that are not conventional
|
|
||||||
filter_unconventional = true
|
|
||||||
# process each line of a commit as an individual commit
|
|
||||||
split_commits = false
|
|
||||||
# regex for preprocessing the commit messages
|
|
||||||
commit_preprocessors = [
|
|
||||||
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "([#${2}](<REPO>/issues/${2}))"}, # replace issue numbers
|
|
||||||
]
|
|
||||||
# regex for parsing and grouping commits
|
|
||||||
commit_parsers = [
|
|
||||||
{ message = "^feat", group = "Features" },
|
|
||||||
{ message = "^fix", group = "Bug Fixes" },
|
|
||||||
{ message = "^doc", group = "Documentation" },
|
|
||||||
{ message = "^perf", group = "Performance" },
|
|
||||||
{ message = "^refactor", group = "Refactor" },
|
|
||||||
{ message = "^style", group = "Styling" },
|
|
||||||
{ message = "^test", group = "Testing" },
|
|
||||||
{ message = "^chore\\(release\\)", skip = true },
|
|
||||||
{ message = "^chore\\(deps\\)", skip = true },
|
|
||||||
{ message = "^chore\\(pr\\)", skip = true },
|
|
||||||
{ message = "^chore\\(pull\\)", skip = true },
|
|
||||||
{ message = "^chore|ci", group = "Miscellaneous Tasks" },
|
|
||||||
{ body = ".*security", group = "Security" },
|
|
||||||
{ message = "^revert", group = "Revert" },
|
|
||||||
]
|
|
||||||
# protect breaking changes from being skipped due to matching a skipping commit_parser
|
|
||||||
protect_breaking_commits = false
|
|
||||||
# filter out the commits that are not matched by commit parsers
|
|
||||||
filter_commits = false
|
|
||||||
# regex for matching git tags
|
|
||||||
tag_pattern = "[0-9].*"
|
|
||||||
|
|
||||||
# regex for skipping tags
|
|
||||||
skip_tags = "v0.1.0-beta.1"
|
|
||||||
# regex for ignoring tags
|
|
||||||
ignore_tags = ""
|
|
||||||
# sort the tags topologically
|
|
||||||
topo_order = false
|
|
||||||
# sort the commits inside sections by oldest/newest order
|
|
||||||
sort_commits = "newest"
|
|
||||||
# limit the number of commits included in the changelog.
|
|
||||||
# limit_commits = 42
|
|
||||||
144
judas_server/web/static/css/style.css
Normal file
144
judas_server/web/static/css/style.css
Normal file
@@ -0,0 +1,144 @@
|
|||||||
|
:root {
|
||||||
|
--nord-bg0: #2e3440;
|
||||||
|
--nord-bg1: #3b4252;
|
||||||
|
--nord-bg2: #434c5e;
|
||||||
|
--nord-bg3: #4c566a;
|
||||||
|
--nord-fg0: #eceff4;
|
||||||
|
--nord-fg1: #e5e9f0;
|
||||||
|
--nord-fg2: #d8dee9;
|
||||||
|
--nord-acc0: #8fbcbb;
|
||||||
|
--nord-acc1: #88c0d0;
|
||||||
|
--nord-acc2: #81a1c1;
|
||||||
|
--nord-acc3: #5e81ac;
|
||||||
|
--nord-aur0: #bf616a;
|
||||||
|
--nord-aur1: #d08770;
|
||||||
|
--nord-aur2: #ebcb8b;
|
||||||
|
--nord-aur3: #a3be8c;
|
||||||
|
--nord-aur4: #b48ead;
|
||||||
|
}
|
||||||
|
|
||||||
|
* {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
background-color: var(--nord-aur4);
|
||||||
|
font-family: monospace, sans-serif !important;
|
||||||
|
color: var(--nord-fg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
font-family: inherit;
|
||||||
|
color: #eceff4;
|
||||||
|
background-color: var(--nord-bg2);
|
||||||
|
border: none;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
padding: 0.25rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#wrapper {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
header {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
background-color: var(--nord-bg0);
|
||||||
|
color: var(--nord-fg0);
|
||||||
|
padding: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
padding: 1rem;
|
||||||
|
background-color: var(--nord-bg1);
|
||||||
|
flex-grow: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
header a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: var(--nord-fg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0.5rem 1rem;
|
||||||
|
background-color: #8fbcbb;
|
||||||
|
color: var(--nord-bg0);
|
||||||
|
border: none;
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
text-decoration: none;
|
||||||
|
transition: 0.3s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button:hover {
|
||||||
|
background-color: var(--nord-acc2);
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center {
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.center-table {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-table{
|
||||||
|
border-collapse: collapse;
|
||||||
|
border: 2px solid var(--nord-fg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-table thead {
|
||||||
|
position: sticky;
|
||||||
|
top: -1px;
|
||||||
|
z-index: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-table th, .select-table td {
|
||||||
|
padding: 0.5rem;
|
||||||
|
text-align: center;
|
||||||
|
border: 1px solid var(--nord-fg1);
|
||||||
|
border-collapse: collapse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-table th {
|
||||||
|
background-color: var(--nord-bg2);
|
||||||
|
color: var(--nord-fg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-table a {
|
||||||
|
display: block;
|
||||||
|
color: var(--nord-acc0);
|
||||||
|
text-decoration: none;
|
||||||
|
transition: 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-table tr {
|
||||||
|
transition: 0.1s ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-table tr:hover {
|
||||||
|
background-color: var(--nord-acc1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-table tr:hover a {
|
||||||
|
color: var(--nord-bg0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.red-bg {
|
||||||
|
background-color: var(--nord-aur0);
|
||||||
|
}
|
||||||
|
|
||||||
|
.yellow-bg {
|
||||||
|
background-color: var(--nord-aur2);
|
||||||
|
}
|
||||||
|
|
||||||
|
.green-bg {
|
||||||
|
background-color: var(--nord-aur3);
|
||||||
|
}
|
||||||
@@ -9,8 +9,8 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<header>
|
<header>
|
||||||
<h1><a href="{{ url_for('panel') }}">judas panel</a></h1>
|
<h1><a href="{{ url_for('index') }}">judas</a></h1>
|
||||||
<p>Welcome, {{ username }}! <a href="{{ url_for('logout') }}">Logout</a></p>
|
<p><a class="button" href="{{ url_for('logout') }}">Logout</a></p>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<h2>Details for PC ID: {{ pc.id }}</h2>
|
<h2>Details for PC ID: {{ pc.id }}</h2>
|
||||||
49
judas_server/web/templates/index.html
Normal file
49
judas_server/web/templates/index.html
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>judas</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="wrapper">
|
||||||
|
<header>
|
||||||
|
<h1><a href="{{ url_for('index') }}">judas</a></h1>
|
||||||
|
{% if logged %}
|
||||||
|
<p>Welcome, {{ username }}! <a href="{{ url_for('logout') }}">Logout</a></p>
|
||||||
|
{% else %}
|
||||||
|
<p><a class="button" href="{{ url_for('login') }}">Login</a></p>
|
||||||
|
{% endif %}
|
||||||
|
</header>
|
||||||
|
<main class="center">
|
||||||
|
<p>Welcome to</p>
|
||||||
|
<h2 id="typing-text" style="font-size: 3rem;">judas</h2>
|
||||||
|
<p>a remote PC fleet management system</p>
|
||||||
|
<br>
|
||||||
|
<p style="color: #bf616a;"><strong>Notice:</strong> Please use this system responsibly and in accordance with all applicable laws and organizational policies.</p>
|
||||||
|
<p>Please log in to manage your remote PCs.</p>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
var i = 0;
|
||||||
|
var txt = document.getElementById("typing-text").innerHTML;
|
||||||
|
var minSpeed = 50;
|
||||||
|
var maxSpeed = 200;
|
||||||
|
|
||||||
|
document.getElementById("typing-text").innerHTML = "";
|
||||||
|
|
||||||
|
function typeWriter() {
|
||||||
|
if (i < txt.length) {
|
||||||
|
document.getElementById("typing-text").innerHTML += txt.charAt(i);
|
||||||
|
i++;
|
||||||
|
|
||||||
|
var randomDelay = Math.floor(Math.random() * (maxSpeed - minSpeed + 1)) + minSpeed;
|
||||||
|
setTimeout(typeWriter, randomDelay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
typeWriter();
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
24
judas_server/web/templates/login.html
Normal file
24
judas_server/web/templates/login.html
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>judas - login page</title>
|
||||||
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="wrapper">
|
||||||
|
<header>
|
||||||
|
<h1><a href="{{ url_for('index') }}">judas</a></h1>
|
||||||
|
</header>
|
||||||
|
<main class="center">
|
||||||
|
<form method="post">
|
||||||
|
<label for="password">Password:</label>
|
||||||
|
<input type="password" id="password" name="password" required>
|
||||||
|
<br><br>
|
||||||
|
<input type="submit" value="Login" class="button">
|
||||||
|
</form>
|
||||||
|
</main>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -9,11 +9,14 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<header>
|
<header>
|
||||||
<h1><a href="{{ url_for('panel') }}">judas panel</a></h1>
|
<h1><a href="{{ url_for('index') }}">judas</a></h1>
|
||||||
<p>Welcome, {{ username }}! <a href="{{ url_for('logout') }}">Logout</a></p>
|
<p><a class="button" href="{{ url_for('logout') }}">Logout</a></p>
|
||||||
</header>
|
</header>
|
||||||
<main>
|
<main>
|
||||||
<table border="1">
|
<h2 class="center">Select a PC to Control</h2>
|
||||||
|
<p class="center">Choose a PC from the list below to view details or send commands.</p>
|
||||||
|
<br>
|
||||||
|
<table class="center-table select-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>PC ID</th>
|
<th>PC ID</th>
|
||||||
@@ -25,8 +28,7 @@
|
|||||||
{% for pc in pcs.values() %}
|
{% for pc in pcs.values() %}
|
||||||
<tr>
|
<tr>
|
||||||
<td><a href="{{ url_for('details', pc_id=pc.id) }}">{{ pc.id }}</a></td>
|
<td><a href="{{ url_for('details', pc_id=pc.id) }}">{{ pc.id }}</a></td>
|
||||||
<td>{{ pc.status if pc.status else 'Unknown' }}</td>
|
<td class='{% if pc.status == "online" %}green-bg{% elif pc.status == "offline" %}red-bg{% else %}yellow-bg{% endif %}'>{{ pc.status if pc.status else 'Unknown' }}</td> <td>{{ pc.last_seen if pc.last_seen else 'Never' }}</td>
|
||||||
<td>{{ pc.last_seen if pc.last_seen else 'Never' }}</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
{% else %}
|
{% else %}
|
||||||
<tr>
|
<tr>
|
||||||
@@ -8,8 +8,8 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="wrapper">
|
<div id="wrapper">
|
||||||
<header>
|
<header>
|
||||||
<h1><a href="{{ url_for('panel') }}">judas panel</a></h1>
|
<h1><a href="{{ url_for('index') }}">judas</a></h1>
|
||||||
<p>Welcome, {{ username }}! <a href="{{ url_for('logout') }}">Logout</a></p>
|
<p><a class="button" href="{{ url_for('logout') }}">Logout</a></p>
|
||||||
</header>
|
</header>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
@@ -17,14 +17,39 @@ login_manager.init_app(app)
|
|||||||
PC_DETAILS = {
|
PC_DETAILS = {
|
||||||
"PC1": {
|
"PC1": {
|
||||||
"id": "PC1",
|
"id": "PC1",
|
||||||
"status": "Online",
|
"status": "online",
|
||||||
"last_seen": "2023-10-01 12:00:00",
|
"last_seen": "2023-10-01 12:00:00",
|
||||||
},
|
},
|
||||||
"PC2": {
|
"PC2": {
|
||||||
"id": "PC2",
|
"id": "PC2",
|
||||||
"status": "Offline",
|
"status": "offline",
|
||||||
"last_seen": "2023-10-01 11:00:00",
|
"last_seen": "2023-10-01 11:00:00",
|
||||||
},
|
},
|
||||||
|
"PC3": {
|
||||||
|
"id": "PC3",
|
||||||
|
"status": "offline",
|
||||||
|
"last_seen": "2023-10-01 11:00:00",
|
||||||
|
},
|
||||||
|
"PC4": {
|
||||||
|
"id": "PC4",
|
||||||
|
"status": "offline",
|
||||||
|
"last_seen": "2023-10-01 11:00:00",
|
||||||
|
},
|
||||||
|
"PC5": {
|
||||||
|
"id": "PC5",
|
||||||
|
"status": "offline",
|
||||||
|
"last_seen": "2023-10-01 11:00:00",
|
||||||
|
},
|
||||||
|
"PC6": {
|
||||||
|
"id": "PC6",
|
||||||
|
"status": "offline",
|
||||||
|
"last_seen": "2023-10-01 11:00:00",
|
||||||
|
},
|
||||||
|
"PC7": {
|
||||||
|
"id": "PC7",
|
||||||
|
"status": "offline",
|
||||||
|
"last_seen": "2023-10-01 11:00:00",
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -52,12 +77,10 @@ def load_user(user_id: str) -> User | None:
|
|||||||
|
|
||||||
|
|
||||||
@app.route("/")
|
@app.route("/")
|
||||||
def index() -> str:
|
def index() -> flask.Response | str:
|
||||||
"""Renders the index page with a link to the login page."""
|
"""Renders the index page with a link to the login page."""
|
||||||
if flask_login.current_user.is_authenticated:
|
if flask_login.current_user.is_authenticated:
|
||||||
return flask.render_template(
|
return flask.redirect(flask.url_for("panel"))
|
||||||
"index.html", logged=True, username=flask_login.current_user.id
|
|
||||||
)
|
|
||||||
else:
|
else:
|
||||||
return flask.render_template(
|
return flask.render_template(
|
||||||
"index.html", logged=False, login_url=flask.url_for("login")
|
"index.html", logged=False, login_url=flask.url_for("login")
|
||||||
@@ -75,12 +98,7 @@ def login() -> str:
|
|||||||
return flask.redirect(flask.url_for("panel"))
|
return flask.redirect(flask.url_for("panel"))
|
||||||
else:
|
else:
|
||||||
return "Invalid password", 401
|
return "Invalid password", 401
|
||||||
return """
|
return flask.render_template("login.html")
|
||||||
<form method="post">
|
|
||||||
Password: <input type="password" name="password">
|
|
||||||
<input type="submit" value="Login">
|
|
||||||
</form>
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
@app.route("/logout")
|
@app.route("/logout")
|
||||||
152
pdm.lock
generated
Normal file
152
pdm.lock
generated
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
# This file is @generated by PDM.
|
||||||
|
# It is not intended for manual editing.
|
||||||
|
|
||||||
|
[metadata]
|
||||||
|
groups = ["default"]
|
||||||
|
strategy = ["inherit_metadata"]
|
||||||
|
lock_version = "4.5.0"
|
||||||
|
content_hash = "sha256:33af03e7c1a19cb9adf4ddcd48bdeae7698363a45eb44d8beda6dd14c7f8f96d"
|
||||||
|
|
||||||
|
[[metadata.targets]]
|
||||||
|
requires_python = ">=3.13"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "blinker"
|
||||||
|
version = "1.9.0"
|
||||||
|
requires_python = ">=3.9"
|
||||||
|
summary = "Fast, simple object-to-object and broadcast signaling"
|
||||||
|
groups = ["default"]
|
||||||
|
files = [
|
||||||
|
{file = "blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc"},
|
||||||
|
{file = "blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "click"
|
||||||
|
version = "8.2.1"
|
||||||
|
requires_python = ">=3.10"
|
||||||
|
summary = "Composable command line interface toolkit"
|
||||||
|
groups = ["default"]
|
||||||
|
dependencies = [
|
||||||
|
"colorama; platform_system == \"Windows\"",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b"},
|
||||||
|
{file = "click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "colorama"
|
||||||
|
version = "0.4.6"
|
||||||
|
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
|
||||||
|
summary = "Cross-platform colored terminal text."
|
||||||
|
groups = ["default"]
|
||||||
|
marker = "platform_system == \"Windows\""
|
||||||
|
files = [
|
||||||
|
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
|
||||||
|
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flask"
|
||||||
|
version = "3.1.1"
|
||||||
|
requires_python = ">=3.9"
|
||||||
|
summary = "A simple framework for building complex web applications."
|
||||||
|
groups = ["default"]
|
||||||
|
dependencies = [
|
||||||
|
"blinker>=1.9.0",
|
||||||
|
"click>=8.1.3",
|
||||||
|
"importlib-metadata>=3.6.0; python_version < \"3.10\"",
|
||||||
|
"itsdangerous>=2.2.0",
|
||||||
|
"jinja2>=3.1.2",
|
||||||
|
"markupsafe>=2.1.1",
|
||||||
|
"werkzeug>=3.1.0",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "flask-3.1.1-py3-none-any.whl", hash = "sha256:07aae2bb5eaf77993ef57e357491839f5fd9f4dc281593a81a9e4d79a24f295c"},
|
||||||
|
{file = "flask-3.1.1.tar.gz", hash = "sha256:284c7b8f2f58cb737f0cf1c30fd7eaf0ccfcde196099d24ecede3fc2005aa59e"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "flask-login"
|
||||||
|
version = "0.6.3"
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = "User authentication and session management for Flask."
|
||||||
|
groups = ["default"]
|
||||||
|
dependencies = [
|
||||||
|
"Flask>=1.0.4",
|
||||||
|
"Werkzeug>=1.0.1",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "Flask-Login-0.6.3.tar.gz", hash = "sha256:5e23d14a607ef12806c699590b89d0f0e0d67baeec599d75947bf9c147330333"},
|
||||||
|
{file = "Flask_Login-0.6.3-py3-none-any.whl", hash = "sha256:849b25b82a436bf830a054e74214074af59097171562ab10bfa999e6b78aae5d"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itsdangerous"
|
||||||
|
version = "2.2.0"
|
||||||
|
requires_python = ">=3.8"
|
||||||
|
summary = "Safely pass data to untrusted environments and back."
|
||||||
|
groups = ["default"]
|
||||||
|
files = [
|
||||||
|
{file = "itsdangerous-2.2.0-py3-none-any.whl", hash = "sha256:c6242fc49e35958c8b15141343aa660db5fc54d4f13a1db01a3f5891b98700ef"},
|
||||||
|
{file = "itsdangerous-2.2.0.tar.gz", hash = "sha256:e0050c0b7da1eea53ffaf149c0cfbb5c6e2e2b69c4bef22c81fa6eb73e5f6173"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "jinja2"
|
||||||
|
version = "3.1.6"
|
||||||
|
requires_python = ">=3.7"
|
||||||
|
summary = "A very fast and expressive template engine."
|
||||||
|
groups = ["default"]
|
||||||
|
dependencies = [
|
||||||
|
"MarkupSafe>=2.0",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"},
|
||||||
|
{file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "markupsafe"
|
||||||
|
version = "3.0.2"
|
||||||
|
requires_python = ">=3.9"
|
||||||
|
summary = "Safely add untrusted strings to HTML/XML markup."
|
||||||
|
groups = ["default"]
|
||||||
|
files = [
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"},
|
||||||
|
{file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"},
|
||||||
|
{file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"},
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "werkzeug"
|
||||||
|
version = "3.1.3"
|
||||||
|
requires_python = ">=3.9"
|
||||||
|
summary = "The comprehensive WSGI web application library."
|
||||||
|
groups = ["default"]
|
||||||
|
dependencies = [
|
||||||
|
"MarkupSafe>=2.1.1",
|
||||||
|
]
|
||||||
|
files = [
|
||||||
|
{file = "werkzeug-3.1.3-py3-none-any.whl", hash = "sha256:54b78bf3716d19a65be4fceccc0d1d7b89e608834989dfae50ea87564639213e"},
|
||||||
|
{file = "werkzeug-3.1.3.tar.gz", hash = "sha256:60723ce945c19328679790e3282cc758aa4a6040e4bb330f53d30fa546d44746"},
|
||||||
|
]
|
||||||
@@ -1,80 +1,17 @@
|
|||||||
[build-system]
|
|
||||||
requires = ["uv_build>=0.7.15,<0.8.0"]
|
|
||||||
build-backend = "uv_build"
|
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "judas_server"
|
name = "judas_server"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
description = "The backbone of the remote PC fleet management system."
|
description = "Default template for PDM package"
|
||||||
readme = "README.md"
|
authors = [
|
||||||
authors = []
|
{name = "Artur Borecki", email = "me@pufereq.pl"},
|
||||||
requires-python = ">=3.13"
|
]
|
||||||
dependencies = ["flask>=3.1.1", "flask-login>=0.6.3"]
|
dependencies = ["flask>=3.1.1", "flask-login>=0.6.3"]
|
||||||
license = { text = "GPL-3.0+" }
|
requires-python = ">=3.13"
|
||||||
|
readme = "README.md"
|
||||||
|
license = {text = "GPL-3.0"}
|
||||||
|
|
||||||
[dependency-groups]
|
[tool.pdm.scripts]
|
||||||
bump = ["git-cliff>=2.9.1", "python-semantic-release>=10.2.0"]
|
web = "flask --app judas_server/web/web_server.py run"
|
||||||
test = [
|
|
||||||
"pytest>=4.2.1",
|
|
||||||
"pytest-cov>=6.2.1",
|
|
||||||
"pytest-github-actions-annotate-failures>=0.3.0",
|
|
||||||
"pytest-mock>=3.14.1",
|
|
||||||
]
|
|
||||||
|
|
||||||
[tool.ruff]
|
[tool.pdm]
|
||||||
line-length = 79
|
distribution = false
|
||||||
exclude = ["tests/*"]
|
|
||||||
|
|
||||||
[tool.ruff.lint.pycodestyle]
|
|
||||||
max-line-length = 79
|
|
||||||
|
|
||||||
[tool.ruff.lint.per-file-ignores]
|
|
||||||
"__init__.py" = ["E402", "F401"]
|
|
||||||
"**/{tests,docs,tools}/*" = ["E402"]
|
|
||||||
|
|
||||||
[tool.ruff.format]
|
|
||||||
docstring-code-format = true
|
|
||||||
docstring-code-line-length = 72
|
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
|
||||||
addopts = [
|
|
||||||
"--cov-report=term-missing",
|
|
||||||
"--cov-report=html",
|
|
||||||
"--cov-fail-under=100",
|
|
||||||
]
|
|
||||||
|
|
||||||
[tool.coverage.run]
|
|
||||||
omit = ["src/judas_server/__init__.py", "examples/*", "docs/*", "tests/*"]
|
|
||||||
|
|
||||||
[tool.semantic_release]
|
|
||||||
version_variables = ["src/judas_server/__init__.py:__version__"]
|
|
||||||
version_toml = ["pyproject.toml:project.version"]
|
|
||||||
build_command_env = []
|
|
||||||
commit_message = "chore(release): {version}\n\nAutomatically generated by python-semantic-release"
|
|
||||||
commit_parser = "conventional"
|
|
||||||
logging_use_named_masks = false
|
|
||||||
major_on_zero = true
|
|
||||||
allow_zero_version = true
|
|
||||||
no_git_verify = false
|
|
||||||
tag_format = "{version}"
|
|
||||||
|
|
||||||
[tool.semantic_release.commit_author]
|
|
||||||
env = "GIT_COMMIT_AUTHOR"
|
|
||||||
default = "semantic-release <semantic-release>"
|
|
||||||
|
|
||||||
[tool.semantic_release.commit_parser_options]
|
|
||||||
allowed_tags = [
|
|
||||||
"build",
|
|
||||||
"chore",
|
|
||||||
"ci",
|
|
||||||
"docs",
|
|
||||||
"feat",
|
|
||||||
"fix",
|
|
||||||
"perf",
|
|
||||||
"style",
|
|
||||||
"refactor",
|
|
||||||
"test",
|
|
||||||
]
|
|
||||||
minor_tags = ["feat"]
|
|
||||||
patch_tags = ["fix", "perf"]
|
|
||||||
default_bump_level = 0
|
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
background-color: #2e3440;
|
|
||||||
color: #eceff4;
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
|
||||||
padding: 2rem;
|
|
||||||
background-color: #eceff4;
|
|
||||||
color: #2e3440;
|
|
||||||
}
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>judas</title>
|
|
||||||
<link rel="stylesheet" href="{{ url_for('static', filename='css/style.css') }}">
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div id="wrapper">
|
|
||||||
<header>
|
|
||||||
<h1>judas</h1>
|
|
||||||
{% if logged %}
|
|
||||||
<p>Welcome, {{ username }}! <a href="{{ url_for('logout') }}">Logout</a></p>
|
|
||||||
{% else %}
|
|
||||||
<p><a href="{{ url_for('login') }}">Login</a></p>
|
|
||||||
{% endif %}
|
|
||||||
</header>
|
|
||||||
</div>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
Reference in New Issue
Block a user