diff --git a/pyproject.toml b/pyproject.toml index a58551e..7bfa78e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -26,6 +26,7 @@ dependencies = [ "requests>=2.34.2", "rq>=2.12.0", "psycopg[binary]>=3.3.6", + "tzdata>=2026.4", ] [build-system] diff --git a/src/makeitso/__init__.py b/src/makeitso/__init__.py index 7d80f40..d22f2ff 100644 --- a/src/makeitso/__init__.py +++ b/src/makeitso/__init__.py @@ -4,6 +4,7 @@ from makeitso.config import configs from makeitso.extensions import bootstrap, csrf, db, job_queue, migrate, oauth +from makeitso.local_time import local_time def create_app(config_name: str | None = None) -> Flask: @@ -23,6 +24,7 @@ def create_app(config_name: str | None = None) -> Flask: migrate.init_app(app, db) job_queue.init_app(app) oauth.init_app(app) + app.add_template_filter(local_time) from makeitso import models # noqa: F401 (registers the models with SQLAlchemy) from makeitso.auth import bp as auth_bp diff --git a/src/makeitso/local_time.py b/src/makeitso/local_time.py new file mode 100644 index 0000000..2b7e822 --- /dev/null +++ b/src/makeitso/local_time.py @@ -0,0 +1,11 @@ +from datetime import UTC, datetime +from zoneinfo import ZoneInfo + +LOCAL_TZ = ZoneInfo("America/Vancouver") + + +def local_time(dt: datetime, fmt: str = "%b %d, %Y %H:%M Vancouver time") -> str: + # Naive datetimes are UTC + if dt.tzinfo is None: + dt = dt.replace(tzinfo=UTC) + return dt.astimezone(LOCAL_TZ).strftime(fmt) diff --git a/src/makeitso/monitor/monitor.py b/src/makeitso/monitor/monitor.py index 4d321bc..5533bc8 100644 --- a/src/makeitso/monitor/monitor.py +++ b/src/makeitso/monitor/monitor.py @@ -13,6 +13,7 @@ ) from makeitso.extensions import job_queue +from makeitso.local_time import local_time # Most jobs to show per queue and per registry, so old failed jobs don't pile up on the page MAX_JOBS = 50 @@ -73,7 +74,7 @@ def get_queue_data(queue: Queue): JobData( id=job.id, status=job.get_status().value, - started_at=(job.started_at.strftime("%b %d, %Y %H:%M") if job.started_at else None), + started_at=(local_time(job.started_at) if job.started_at else None), execution_time=_execution_time(job), ) for job in jobs diff --git a/src/makeitso/stacks/forms.py b/src/makeitso/stacks/forms.py index d21da6a..6839413 100644 --- a/src/makeitso/stacks/forms.py +++ b/src/makeitso/stacks/forms.py @@ -1,6 +1,6 @@ from flask_wtf import FlaskForm from github import GithubException -from wtforms import BooleanField, Field, StringField, TextAreaField +from wtforms import BooleanField, Field, StringField, SubmitField, TextAreaField from wtforms.validators import DataRequired, Regexp, ValidationError from makeitso.extensions import db @@ -81,13 +81,14 @@ def _strip(value: str | None) -> str | None: class LockForm(FlaskForm): - locked = BooleanField("Lock this stack") + lock = SubmitField("Lock") + unlock = SubmitField("Unlock") lock_reason = TextAreaField( "Reason", description="Shown on the stack page. Needed when locking.", filters=[_strip] ) def validate_lock_reason(self, field: Field) -> None: - if self.locked.data and not field.data: + if self.lock.data and not field.data: raise ValidationError("Give a reason for locking the stack") diff --git a/src/makeitso/stacks/views/settings.py b/src/makeitso/stacks/views/settings.py index dcb7e64..df2ff19 100644 --- a/src/makeitso/stacks/views/settings.py +++ b/src/makeitso/stacks/views/settings.py @@ -47,7 +47,7 @@ def post(self, stack_id: int): form = _lock_form(stack) if not form.validate_on_submit(): return _render(stack, form, _env_var_form()) - stack.locked = form.locked.data + stack.locked = form.lock.data stack.lock_reason = form.lock_reason.data if stack.locked else None db.session.commit() flash("Stack locked" if stack.locked else "Stack unlocked", "success") diff --git a/src/makeitso/templates/deploys/detail.html b/src/makeitso/templates/deploys/detail.html index b6a931d..42b5a26 100644 --- a/src/makeitso/templates/deploys/detail.html +++ b/src/makeitso/templates/deploys/detail.html @@ -23,7 +23,7 @@
{{ deploy.commit.commit_message }}
{% set details = [ ("person", "Author", deploy.commit.author_name), - ("clock", "Started", deploy.started_at.strftime("%b %d, %Y %H:%M")), + ("clock", "Started", deploy.started_at|local_time), ("person-check", "Deployed by", deployed_by(deploy)), ] %}{{ stack.branch }}{{ commit.short_sha }} · {{ commit.committed_at.strftime("%b %d, %Y %H:%M") }}
+ {{ commit.short_sha }} · {{ commit.committed_at|local_time }}
Syncing with GitHub…
{% else %}- {% if stack.synced_at %}Last synced {{ stack.synced_at.strftime("%b %d, %Y %H:%M") }}{% else %}Never synced{% endif %} + {% if stack.synced_at %}Last synced {{ stack.synced_at|local_time }}{% else %}Never synced{% endif %}
{% endif %} @@ -85,7 +85,7 @@