This commit is contained in:
Daniel Grams 2020-12-30 19:11:26 +01:00
parent 3b123eb7a8
commit eb0c585eeb
4 changed files with 168 additions and 5 deletions

View File

@ -0,0 +1,106 @@
"""empty message
Revision ID: e33f225323f3
Revises: 7b105c6e08bf
Create Date: 2020-12-30 17:59:47.917389
"""
from alembic import op
import sqlalchemy as sa
import sqlalchemy_utils
from project import dbtypes
# revision identifiers, used by Alembic.
revision = "e33f225323f3"
down_revision = "7b105c6e08bf"
branch_labels = None
depends_on = None
def upgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.add_column("adminunit", sa.Column("updated_at", sa.DateTime(), nullable=True))
op.add_column("adminunit", sa.Column("updated_by_id", sa.Integer(), nullable=True))
op.create_foreign_key(None, "adminunit", "user", ["updated_by_id"], ["id"])
op.add_column("event", sa.Column("updated_at", sa.DateTime(), nullable=True))
op.add_column("event", sa.Column("updated_by_id", sa.Integer(), nullable=True))
op.create_foreign_key(None, "event", "user", ["updated_by_id"], ["id"])
op.add_column(
"eventorganizer", sa.Column("updated_at", sa.DateTime(), nullable=True)
)
op.add_column(
"eventorganizer", sa.Column("updated_by_id", sa.Integer(), nullable=True)
)
op.create_foreign_key(None, "eventorganizer", "user", ["updated_by_id"], ["id"])
op.add_column("eventplace", sa.Column("updated_at", sa.DateTime(), nullable=True))
op.add_column("eventplace", sa.Column("updated_by_id", sa.Integer(), nullable=True))
op.create_foreign_key(None, "eventplace", "user", ["updated_by_id"], ["id"])
op.add_column(
"eventreference", sa.Column("updated_at", sa.DateTime(), nullable=True)
)
op.add_column(
"eventreference", sa.Column("updated_by_id", sa.Integer(), nullable=True)
)
op.create_foreign_key(None, "eventreference", "user", ["updated_by_id"], ["id"])
op.add_column(
"eventreferencerequest", sa.Column("updated_at", sa.DateTime(), nullable=True)
)
op.add_column(
"eventreferencerequest", sa.Column("updated_by_id", sa.Integer(), nullable=True)
)
op.create_foreign_key(
None, "eventreferencerequest", "user", ["updated_by_id"], ["id"]
)
op.add_column(
"eventsuggestion", sa.Column("updated_at", sa.DateTime(), nullable=True)
)
op.add_column(
"eventsuggestion", sa.Column("updated_by_id", sa.Integer(), nullable=True)
)
op.create_foreign_key(None, "eventsuggestion", "user", ["updated_by_id"], ["id"])
op.add_column("image", sa.Column("updated_at", sa.DateTime(), nullable=True))
op.add_column("image", sa.Column("updated_by_id", sa.Integer(), nullable=True))
op.create_foreign_key(None, "image", "user", ["updated_by_id"], ["id"])
op.add_column("location", sa.Column("updated_at", sa.DateTime(), nullable=True))
op.add_column("location", sa.Column("updated_by_id", sa.Integer(), nullable=True))
op.create_foreign_key(None, "location", "user", ["updated_by_id"], ["id"])
op.add_column("settings", sa.Column("updated_at", sa.DateTime(), nullable=True))
op.add_column("settings", sa.Column("updated_by_id", sa.Integer(), nullable=True))
op.create_foreign_key(None, "settings", "user", ["updated_by_id"], ["id"])
# ### end Alembic commands ###
def downgrade():
# ### commands auto generated by Alembic - please adjust! ###
op.drop_constraint(None, "settings", type_="foreignkey")
op.drop_column("settings", "updated_by_id")
op.drop_column("settings", "updated_at")
op.drop_constraint(None, "location", type_="foreignkey")
op.drop_column("location", "updated_by_id")
op.drop_column("location", "updated_at")
op.drop_constraint(None, "image", type_="foreignkey")
op.drop_column("image", "updated_by_id")
op.drop_column("image", "updated_at")
op.drop_constraint(None, "eventsuggestion", type_="foreignkey")
op.drop_column("eventsuggestion", "updated_by_id")
op.drop_column("eventsuggestion", "updated_at")
op.drop_constraint(None, "eventreferencerequest", type_="foreignkey")
op.drop_column("eventreferencerequest", "updated_by_id")
op.drop_column("eventreferencerequest", "updated_at")
op.drop_constraint(None, "eventreference", type_="foreignkey")
op.drop_column("eventreference", "updated_by_id")
op.drop_column("eventreference", "updated_at")
op.drop_constraint(None, "eventplace", type_="foreignkey")
op.drop_column("eventplace", "updated_by_id")
op.drop_column("eventplace", "updated_at")
op.drop_constraint(None, "eventorganizer", type_="foreignkey")
op.drop_column("eventorganizer", "updated_by_id")
op.drop_column("eventorganizer", "updated_at")
op.drop_constraint(None, "event", type_="foreignkey")
op.drop_column("event", "updated_by_id")
op.drop_column("event", "updated_at")
op.drop_constraint(None, "adminunit", type_="foreignkey")
op.drop_column("adminunit", "updated_by_id")
op.drop_column("adminunit", "updated_at")
# ### end Alembic commands ###

View File

@ -17,7 +17,7 @@ from sqlalchemy import (
Numeric,
)
from sqlalchemy_utils import ColorType
from flask_security import UserMixin, RoleMixin
from flask_security import UserMixin, RoleMixin, current_user
from flask_dance.consumer.storage.sqla import OAuthConsumerMixin
from enum import IntEnum
import datetime
@ -28,16 +28,49 @@ from sqlalchemy import and_
# Base
def _current_user_id_or_none():
if current_user.is_authenticated:
return current_user.id
return None
class TrackableMixin(object):
created_at = Column(DateTime, default=datetime.datetime.utcnow)
updated_at = Column(
DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow
)
@declared_attr
def created_by_id(cls):
return Column("created_by_id", ForeignKey("user.id"))
return Column(
"created_by_id", ForeignKey("user.id"), default=_current_user_id_or_none
)
@declared_attr
def created_by(cls):
return relationship("User")
return relationship(
"User",
primaryjoin="User.id == %s.created_by_id" % cls.__name__,
remote_side="User.id",
)
@declared_attr
def updated_by_id(cls):
return Column(
"updated_by_id",
ForeignKey("user.id"),
default=_current_user_id_or_none,
onupdate=_current_user_id_or_none,
)
@declared_attr
def updated_by(cls):
return relationship(
"User",
primaryjoin="User.id == %s.updated_by_id" % cls.__name__,
remote_side="User.id",
)
# Global

View File

@ -309,6 +309,29 @@
{{ render_enum_prop(reference_request.rejection_reason, 'fa-search-minus', 'Rejection reason') }}
{% endmacro %}
{% macro render_audit(tracking_mixing, show_user=False) %}
{% set created_at = tracking_mixing.created_at | datetimeformat('short') %}
{% set updated_at = tracking_mixing.updated_at | datetimeformat('short') %}
{% if show_user %}
{{ _('Created at %(created_at)s by %(created_by)s.', created_at=created_at, created_by=tracking_mixing.created_by.email) }}
{% else %}
{{ _('Created at %(created_at)s.', created_at=created_at) }}
{% endif %}
{% if created_at != updated_at %}
{% if show_user %}
{{ _('Last updated at %(updated_at)s by %(updated_by)s.', updated_at=updated_at, updated_by=tracking_mixing.updated_by.email) }}
{% else %}
{{ _('Last updated at %(updated_at)s.', updated_at=updated_at) }}
{% endif %}
{% endif %}
{% endmacro %}
{% macro render_audit_container(tracking_mixing, show_user=False) %}
<div class="my-4 small">{{ render_audit(tracking_mixing, show_user) }}</div>
{% endmacro %}
{% macro render_event_props(event, start, end, dates = None, show_rating = False, show_admin_unit = True) %}
<div class="card mb-3">
<div class="card-header">

View File

@ -1,5 +1,5 @@
{% extends "layout.html" %}
{% from "_macros.html" import render_event_menu, render_event_props, render_image_with_link, render_place, render_link_prop %}
{% from "_macros.html" import render_audit_container, render_event_menu, render_event_props, render_image_with_link, render_place, render_link_prop %}
{% block title %}
{{ event.name }}
{% endblock %}
@ -9,7 +9,7 @@
<div class="w-normal">
{{ render_event_props(event, event.start, event.end, dates, user_can_verify_event) }}
{{ render_event_props(event, event.start, event.end, dates, user_rights['can_verify_event']) }}
{% if dates|length > 0 %}
<div class="card mt-4">
@ -24,6 +24,7 @@
</div>
{% endif %}
{{ render_audit_container(event, user_rights['can_verify_event']) }}
</div>
{% endblock %}