74 lines
3.0 KiB
Python
74 lines
3.0 KiB
Python
"""
|
|
Contains the audit log class and functions.
|
|
"""
|
|
from typing import List
|
|
from dateutil.parser import parse
|
|
from sqlalchemy.orm import declarative_base, DeclarativeMeta, Query
|
|
from . import BaseClass
|
|
from sqlalchemy import Column, INTEGER, String, JSON, TIMESTAMP, func
|
|
from datetime import date, datetime, timedelta
|
|
import logging
|
|
|
|
logger = logging.getLogger(f"submissions.{__name__}")
|
|
|
|
Base: DeclarativeMeta = declarative_base()
|
|
|
|
class AuditLog(Base):
|
|
|
|
__tablename__ = "_auditlog"
|
|
|
|
id = Column(INTEGER, primary_key=True, autoincrement=True) #: primary key
|
|
user = Column(String(64))
|
|
time = Column(TIMESTAMP)
|
|
object = Column(String(64))
|
|
changes = Column(JSON)
|
|
|
|
def __repr__(self):
|
|
return f"<{self.object}: {self.user} @ {self.time}>"
|
|
|
|
@classmethod
|
|
def query(cls, start_date: date | str | int | None = None, end_date: date | str | int | None = None) -> List["AuditLog"]:
|
|
"""
|
|
Searches for database transactions by date.
|
|
|
|
Args:
|
|
start_date (date | str | int | None, Optional): Earliest date sought. Defaults to None
|
|
end_date (date | str | int | None, Optional): Latest date sought. Defaults to None
|
|
|
|
Returns:
|
|
List[AuditLog]: List of transactions made to the database.
|
|
"""
|
|
session = BaseClass.__database_session__
|
|
query: Query = session.query(cls)
|
|
if start_date is not None and end_date is None:
|
|
logger.warning(f"Start date with no end date, using today.")
|
|
end_date = date.today()
|
|
if end_date is not None and start_date is None:
|
|
logger.warning(f"End date with no start date, using Jan 1, 2023")
|
|
start_date = session.query(cls, func.min(cls.time)).first()[1]
|
|
if start_date is not None:
|
|
match start_date:
|
|
case date():
|
|
start_date = start_date.strftime("%Y-%m-%d")
|
|
case int():
|
|
start_date = datetime.fromordinal(
|
|
datetime(1900, 1, 1).toordinal() + start_date - 2).date().strftime("%Y-%m-%d")
|
|
case _:
|
|
start_date = parse(start_date).strftime("%Y-%m-%d")
|
|
match end_date:
|
|
case date() | datetime():
|
|
end_date = end_date + timedelta(days=1)
|
|
end_date = end_date.strftime("%Y-%m-%d")
|
|
case int():
|
|
end_date = datetime.fromordinal(datetime(1900, 1, 1).toordinal() + end_date - 2).date() + timedelta(days=1)
|
|
end_date = end_date.strftime("%Y-%m-%d")
|
|
case _:
|
|
end_date = parse(end_date) + timedelta(days=1)
|
|
end_date = end_date.strftime("%Y-%m-%d")
|
|
if start_date == end_date:
|
|
start_date = datetime.strptime(start_date, "%Y-%m-%d").strftime("%Y-%m-%d %H:%M:%S.%f")
|
|
query = query.filter(cls.time == start_date)
|
|
else:
|
|
query = query.filter(cls.time.between(start_date, end_date))
|
|
return query.all()
|