Skip to content

Commit

Permalink
Syntax changes and model update changes (#1056)
Browse files Browse the repository at this point in the history
  • Loading branch information
michplunkett authored Sep 12, 2023
1 parent 15bc056 commit 060d0ab
Show file tree
Hide file tree
Showing 12 changed files with 198 additions and 122 deletions.
17 changes: 12 additions & 5 deletions OpenOversight/app/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
from flask import Flask, current_app, session
from markupsafe import Markup

from OpenOversight.app.utils.constants import FIELD_NOT_AVAILABLE, KEY_TIMEZONE
from OpenOversight.app.utils.constants import (
FIELD_NOT_AVAILABLE,
KEY_TIMEZONE,
OO_DATE_FORMAT,
OO_TIME_FORMAT,
)
from OpenOversight.app.utils.general import AVAILABLE_TIMEZONES


Expand Down Expand Up @@ -47,29 +52,31 @@ def markdown(text: str) -> Markup:
def display_date(value: datetime) -> str:
"""Convert UTC datetime.datetime into a localized date string."""
if value:
return value.strftime("%b %d, %Y")
return value.strftime(OO_DATE_FORMAT)
return FIELD_NOT_AVAILABLE


def local_date(value: datetime) -> str:
"""Convert UTC datetime.datetime into a localized date string."""
if value:
return value.astimezone(get_timezone()).strftime("%b %d, %Y")
return value.astimezone(get_timezone()).strftime(OO_DATE_FORMAT)
return FIELD_NOT_AVAILABLE


def local_date_time(value: datetime) -> str:
"""Convert UTC datetime.datetime into a localized date time string."""
if value:
return value.astimezone(get_timezone()).strftime("%I:%M %p (%Z) on %b %d, %Y")
return value.astimezone(get_timezone()).strftime(
f"{OO_TIME_FORMAT} (%Z) on {OO_DATE_FORMAT}"
)
return FIELD_NOT_AVAILABLE


def display_time(value: datetime) -> str:
"""Convert UTC datetime.datetime into a localized date string."""
# This is used for incident times which are not currently tz-aware
if value:
return value.strftime("%I:%M %p")
return value.strftime(OO_TIME_FORMAT)
return FIELD_NOT_AVAILABLE


Expand Down
6 changes: 3 additions & 3 deletions OpenOversight/app/main/forms.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import datetime
import re
from datetime import datetime, time

from flask_wtf import FlaskForm as Form
from flask_wtf.file import FileAllowed, FileField, FileRequired
Expand Down Expand Up @@ -175,7 +175,7 @@ class SalaryForm(Form):
)
year = IntegerField(
"Year",
default=datetime.datetime.now().year,
default=datetime.now().year,
validators=[NumberRange(min=1900, max=2100)],
)
is_fiscal_year = BooleanField("Is fiscal year?", default=False)
Expand Down Expand Up @@ -434,7 +434,7 @@ class DateFieldForm(Form):
time_field = TimeField("Time", validators=[Optional()])

def validate_time_field(self, field):
if not type(field.data) == datetime.time:
if not type(field.data) == time:
raise ValidationError("Not a valid time.")

def validate_date_field(self, field):
Expand Down
8 changes: 4 additions & 4 deletions OpenOversight/app/main/model_view.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import datetime
from datetime import datetime
from http import HTTPMethod
from typing import Callable, Union

Expand Down Expand Up @@ -219,11 +219,11 @@ def populate_obj(self, form, obj):

# if the object doesn't have a creator id set it to current user
if hasattr(obj, "created_by") and not getattr(obj, "created_by"):
obj.created_by = current_user.get_id()
obj.created_by = current_user.id
# if the object keeps track of who updated it last, set to current user
if hasattr(obj, "last_updated_at"):
obj.last_updated_at = datetime.datetime.now()
obj.last_updated_by = current_user.get_id()
obj.last_updated_at = datetime.now()
obj.last_updated_by = current_user.id

db.session.add(obj)
db.session.commit()
Expand Down
5 changes: 2 additions & 3 deletions OpenOversight/app/main/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ def officer_profile(officer_id: int):
form = AssignmentForm()
try:
officer = Officer.query.filter_by(id=officer_id).one()
officer.incidents.query.order_by(Incident.date.desc(), Incident.time.desc())
except NoResultFound:
abort(HTTPStatus.NOT_FOUND)
except: # noqa: E722
Expand Down Expand Up @@ -1946,8 +1947,6 @@ def server_shutdown(): # pragma: no cover
class IncidentApi(ModelView):
model = Incident
model_name = "incident"
order_by = "date"
descending = True
form = IncidentForm
create_function = create_incident
department_check = True
Expand Down Expand Up @@ -1986,7 +1985,7 @@ def get(self, obj_id: int):
incidents = incidents.filter(self.model.date > after_date)

incidents = incidents.order_by(
getattr(self.model, self.order_by).desc()
Incident.date.desc(), Incident.time.desc()
).paginate(page=page, per_page=self.per_page, error_out=False)

url = f"main.{self.model_name}_api"
Expand Down
50 changes: 37 additions & 13 deletions OpenOversight/app/models/database_imports.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import datetime
from datetime import date, datetime, time
from typing import Any, Dict, Optional, Sequence, Tuple, Union

import dateutil.parser
Expand Down Expand Up @@ -36,13 +36,13 @@ def validate_choice(
return None


def parse_date(date_str: Optional[str]) -> Optional[datetime.date]:
def parse_date(date_str: Optional[str]) -> Optional[date]:
if date_str:
return dateutil.parser.parse(date_str).date()
return None


def parse_time(time_str: Optional[str]) -> Optional[datetime.time]:
def parse_time(time_str: Optional[str]) -> Optional[time]:
if time_str:
return dateutil.parser.parse(time_str).time()
return None
Expand Down Expand Up @@ -73,6 +73,8 @@ def parse_str(value: Optional[str], default: Optional[str] = "") -> Optional[str


def create_officer_from_dict(data: Dict[str, Any], force_id: bool = False) -> Officer:
admin_user = User.query.filter_by(is_administrator=True).first()

officer = Officer(
department_id=int(data["department_id"]),
last_name=parse_str(data.get("last_name", "")),
Expand All @@ -86,6 +88,8 @@ def create_officer_from_dict(data: Dict[str, Any], force_id: bool = False) -> Of
unique_internal_identifier=parse_str(
data.get("unique_internal_identifier"), None
),
created_by=admin_user.id,
last_updated_by=admin_user.id,
)
if force_id and data.get("id"):
officer.id = data["id"]
Expand Down Expand Up @@ -118,20 +122,26 @@ def update_officer_from_dict(data: Dict[str, Any], officer: Officer) -> Officer:
officer.unique_internal_identifier = parse_str(
data.get("unique_internal_identifier"), None
)
officer.last_updated_at = datetime.now()
officer.last_updated_by = User.query.filter_by(is_administrator=True).first().id
db.session.flush()
return officer


def create_assignment_from_dict(
data: Dict[str, Any], force_id: bool = False
) -> Assignment:
admin_user = User.query.filter_by(is_administrator=True).first()

assignment = Assignment(
officer_id=int(data["officer_id"]),
star_no=parse_str(data.get("star_no"), None),
job_id=int(data["job_id"]),
unit_id=parse_int(data.get("unit_id")),
start_date=parse_date(data.get("start_date")),
resign_date=parse_date(data.get("resign_date")),
created_by=admin_user.id,
last_updated_by=admin_user.id,
)
if force_id and data.get("id"):
assignment.id = data["id"]
Expand All @@ -155,18 +165,24 @@ def update_assignment_from_dict(
assignment.start_date = parse_date(data.get("start_date"))
if "resign_date" in data.keys():
assignment.resign_date = parse_date(data.get("resign_date"))
assignment.last_updated_at = datetime.now()
assignment.last_updated_by = User.query.filter_by(is_administrator=True).first().id
db.session.flush()

return assignment


def create_salary_from_dict(data: Dict[str, Any], force_id: bool = False) -> Salary:
admin_user = User.query.filter_by(is_administrator=True).first()

salary = Salary(
officer_id=int(data["officer_id"]),
salary=float(data["salary"]),
overtime_pay=parse_float(data.get("overtime_pay")),
year=int(data["year"]),
is_fiscal_year=parse_bool(data.get("is_fiscal_year")),
created_by=admin_user.id,
last_updated_by=admin_user.id,
)
if force_id and data.get("id"):
salary.id = data["id"]
Expand All @@ -186,19 +202,24 @@ def update_salary_from_dict(data: Dict[str, Any], salary: Salary) -> Salary:
salary.year = int(data["year"])
if "is_fiscal_year" in data.keys():
salary.is_fiscal_year = parse_bool(data.get("is_fiscal_year"))
salary.last_updated_at = datetime.now()
salary.last_updated_by = User.query.filter_by(is_administrator=True).first().id
db.session.flush()

return salary


def create_link_from_dict(data: Dict[str, Any], force_id: bool = False) -> Link:
admin_user = User.query.filter_by(is_administrator=True).first()

link = Link(
title=data.get("title", ""),
url=url_validator(data["url"]),
link_type=validate_choice(data.get("link_type"), LINK_CHOICES),
description=parse_str(data.get("description"), None),
author=parse_str(data.get("author"), None),
created_by=parse_int(data.get("created_by")),
created_by=parse_int(data.get("created_by", admin_user.id)),
last_updated_by=parse_int(data.get("created_by", admin_user.id)),
)

if force_id and data.get("id"):
Expand All @@ -223,12 +244,12 @@ def update_link_from_dict(data: Dict[str, Any], link: Link) -> Link:
link.description = parse_str(data.get("description"), None)
if "author" in data:
link.author = parse_str(data.get("author"), None)
if "created_by" in data:
link.created_by = parse_int(data.get("created_by"))
if "officers" in data:
link.officers = data.get("officers") or []
if "incidents" in data:
link.incidents = data.get("incidents") or []
link.last_updated_at = datetime.now()
link.last_updated_by = User.query.filter_by(is_administrator=True).first().id
db.session.flush()

return link
Expand Down Expand Up @@ -275,16 +296,17 @@ def get_or_create_location_from_dict(


def create_incident_from_dict(data: Dict[str, Any], force_id: bool = False) -> Incident:
admin_user = User.query.filter_by(is_administrator=True).first()

incident = Incident(
date=parse_date(data.get("date")),
time=parse_time(data.get("time")),
report_number=parse_str(data.get("report_number"), None),
description=parse_str(data.get("description"), None),
address_id=data.get("address_id"),
department_id=parse_int(data.get("department_id")),
created_by=parse_int(data.get("created_by")),
last_updated_by=parse_int(data.get("last_updated_by")),
last_updated_at=datetime.datetime.now(),
created_by=parse_int(data.get("created_by", admin_user.id)),
last_updated_by=parse_int(data.get("last_updated_by", admin_user.id)),
)

incident.officers = data.get("officers", [])
Expand All @@ -310,16 +332,18 @@ def update_incident_from_dict(data: Dict[str, Any], incident: Incident) -> Incid
if "address_id" in data:
incident.address_id = data.get("address_id")
if "department_id" in data:
incident.department_id = parse_int(data.get("department_id"))
if "created_by" in data:
incident.created_by = parse_int(data.get("created_by"))
incident.department_id = parse_int(
data.get(
"department_id", User.query.filter_by(is_administrator=True).first().id
)
)
if "last_updated_by" in data:
incident.last_updated_by = parse_int(data.get("last_updated_by"))
incident.last_updated_at = datetime.datetime.now()
if "officers" in data:
incident.officers = data["officers"] or []
if "license_plate_objects" in data:
incident.license_plates = data["license_plate_objects"] or []
incident.last_updated_at = datetime.now()
db.session.flush()
return incident

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ <h3>Incidents</h3>
{% if officer.incidents %}
<table class="table table-hover table-responsive">
<tbody>
{% for incident in officer.incidents | sort(attribute='date') | reverse %}
{% for incident in officer.incidents %}
{% if not loop.first %}
<tr class="border:none">
<td colspan="2">&nbsp;</td>
Expand Down
6 changes: 3 additions & 3 deletions OpenOversight/app/utils/cloud.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import datetime
import hashlib
import os
import sys
from datetime import datetime
from io import BytesIO
from traceback import format_exc
from urllib.request import urlopen
Expand Down Expand Up @@ -122,7 +122,7 @@ def save_image_to_s3_and_db(image_buf, user_id, department_id=None):

date_taken = get_date_taken(pimage)
if date_taken:
date_taken = datetime.datetime.strptime(date_taken, "%Y:%m:%d %H:%M:%S")
date_taken = datetime.strptime(date_taken, "%Y:%m:%d %H:%M:%S")
pimage.getexif().clear()
scrubbed_image_buf = BytesIO()
pimage.save(scrubbed_image_buf, image_format)
Expand All @@ -140,10 +140,10 @@ def save_image_to_s3_and_db(image_buf, user_id, department_id=None):
new_image = Image(
filepath=url,
hash_img=hash_img,
created_at=datetime.datetime.now(),
department_id=department_id,
taken_at=date_taken,
created_by=user_id,
last_updated_by=user_id,
)
db.session.add(new_image)
db.session.commit()
Expand Down
10 changes: 7 additions & 3 deletions OpenOversight/app/utils/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
KEY_DEPT_TOTAL_INCIDENTS = "total_department_incidents"
KEY_DEPT_TOTAL_OFFICERS = "total_department_officers"

# Database Key Constants
KEY_DB_CREATOR = "creator"

# Config Key Constants
KEY_ALLOWED_EXTENSIONS = "ALLOWED_EXTENSIONS"
KEY_DATABASE_URI = "SQLALCHEMY_DATABASE_URI"
Expand All @@ -35,6 +32,13 @@
KEY_S3_BUCKET_NAME = "S3_BUCKET_NAME"
KEY_TIMEZONE = "TIMEZONE"

# Database Key Constants
KEY_DB_CREATOR = "creator"

# DateTime Constants
OO_DATE_FORMAT = "%b %d, %Y"
OO_TIME_FORMAT = "%I:%M %p"

# File Handling Constants
ENCODING_UTF_8 = "utf-8"
FILE_TYPE_HTML = "html"
Expand Down
Loading

0 comments on commit 060d0ab

Please sign in to comment.