From 2e5ea7f43a8b159ebf813ed1d38bdc890e90fce3 Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Mon, 10 Jul 2023 11:18:50 -0500 Subject: [PATCH 01/29] Small views edits --- OpenOversight/app/main/views.py | 38 +++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/OpenOversight/app/main/views.py b/OpenOversight/app/main/views.py index ee6b8c30a..31ad17f6c 100644 --- a/OpenOversight/app/main/views.py +++ b/OpenOversight/app/main/views.py @@ -246,7 +246,7 @@ def officer_profile(officer_id): except NoResultFound: abort(HTTPStatus.NOT_FOUND) except: # noqa: E722 - exception_type, value, full_tback = sys.exc_info() + exception_type, value, full_traceback = sys.exc_info() current_app.logger.error( "Error finding officer: {}".format( " ".join([str(exception_type), str(value), format_exc()]) @@ -272,7 +272,7 @@ def officer_profile(officer_id): # Add in the placeholder image if no faces are found face_paths = [url_for("static", filename="images/placeholder.png")] except: # noqa: E722 - exception_type, value, full_tback = sys.exc_info() + exception_type, value, full_traceback = sys.exc_info() current_app.logger.error( "Error loading officer profile: {}".format( " ".join([str(exception_type), str(value), format_exc()]) @@ -491,7 +491,7 @@ def classify_submission(image_id, contains_cops): flash("Updated image classification") except: # noqa: E722 flash("Unknown error occurred") - exception_type, value, full_tback = sys.exc_info() + exception_type, value, full_traceback = sys.exc_info() current_app.logger.error( "Error classifying image: {}".format( " ".join([str(exception_type), str(value), format_exc()]) @@ -739,8 +739,9 @@ def list_officer( for officer in officers.items: officer_face = sorted(officer.face, key=lambda x: x.featured, reverse=True) - # could do some extra work to not lazy load images but load them all together - # but we would want to ensure to only load the first picture of each officer + # Could do some extra work to not lazy load images but load them all together. + # To do that properly we would want to ensure to only load the first picture of + # each officer. if officer_face and officer_face[0].image: officer.image = officer_face[0].image.filepath @@ -812,7 +813,8 @@ def get_dept_ranks(department_id=None, is_sworn_officer=None): ranks = ranks.order_by(Job.job_title).all() rank_list = [(rank.id, rank.job_title) for rank in ranks] else: - ranks = Job.query.all() # Not filtering by is_sworn_officer + # Not filtering by is_sworn_officer + ranks = Job.query.all() # Prevent duplicate ranks rank_list = sorted( set((rank.id, rank.job_title) for rank in ranks), @@ -863,11 +865,11 @@ def add_officer(): abort(HTTPStatus.FORBIDDEN) if form.validate_on_submit(): # Work around for WTForms limitation with boolean fields in FieldList - new_formdata = request.form.copy() - for key in new_formdata.keys(): + new_form_data = request.form.copy() + for key in new_form_data.keys(): if re.fullmatch(r"salaries-\d+-is_fiscal_year", key): - new_formdata[key] = "y" - form = AddOfficerForm(new_formdata) + new_form_data[key] = "y" + form = AddOfficerForm(new_form_data) officer = add_officer_profile(form, current_user) flash("New Officer {} added to OpenOversight".format(officer.last_name)) return redirect(url_for("main.submit_officer_images", officer_id=officer.id)) @@ -1025,7 +1027,8 @@ def label_data(department_id=None, image_id=None): department = None if image_id: image = Image.query.filter_by(id=image_id).one() - else: # Select a random untagged image from the entire database + else: + # Select a random untagged image from the entire database image_query = Image.query.filter_by(contains_cops=True).filter_by( is_tagged=False ) @@ -1052,9 +1055,8 @@ def label_data(department_id=None, image_id=None): flash("Invalid officer ID. Please select a valid OpenOversight ID!") elif department and officer_exists.department_id != department_id: flash( - "The officer is not in {}. Are you sure that is the correct OpenOversight ID?".format( - department.name - ) + "The officer is not in {}. Are you sure that is the correct " + "OpenOversight ID?".format(department.name) ) elif not existing_tag: left = form.dataX.data @@ -1389,7 +1391,8 @@ def upload(department_id, officer_id=None): image.contains_cops = True face = Face( officer_id=officer_id, - # Assuming photos uploaded with an officer ID are already cropped, so we set both images to the uploaded one + # Assuming photos uploaded with an officer ID are already cropped, + # we set both images to the uploaded one img_id=image.id, original_image_id=image.id, user_id=current_user.get_id(), @@ -1712,7 +1715,10 @@ def dispatch_request(self, *args, **kwargs): class OfficerLinkApi(ModelView): - """This API only applies to links attached to officer profiles, not links attached to incidents""" + """ + This API only applies to links attached to officer profiles, not links attached to + incidents. + """ model = Link model_name = "link" From d16374a266da01bb733b130f804cbb0cc65acfea Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Mon, 10 Jul 2023 11:27:19 -0500 Subject: [PATCH 02/29] Update email_client.py --- OpenOversight/app/email_client.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/OpenOversight/app/email_client.py b/OpenOversight/app/email_client.py index 83568c9ee..9a860135d 100644 --- a/OpenOversight/app/email_client.py +++ b/OpenOversight/app/email_client.py @@ -18,17 +18,15 @@ class EmailClient(object): _instance = None - def __new__(cls, dev=False, testing=False): + def __new__(cls, config=None, dev=False, testing=False): if (testing or dev) and cls._instance is None: cls._instance = {} - if cls._instance is None: + if cls._instance is None and config: credentials = service_account.Credentials.from_service_account_file( SERVICE_ACCOUNT_FILE, scopes=cls.SCOPES ) - delegated_credentials = credentials.with_subject( - current_app.config["OO_SERVICE_EMAIL"] - ) + delegated_credentials = credentials.with_subject(config["OO_SERVICE_EMAIL"]) cls.service = build("gmail", "v1", credentials=delegated_credentials) cls._instance = super(EmailClient, cls).__new__(cls) return cls._instance From e7e2e340e556eaee2b2122251d6e881e354f83e7 Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Mon, 10 Jul 2023 11:27:21 -0500 Subject: [PATCH 03/29] Update __init__.py --- OpenOversight/app/__init__.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/OpenOversight/app/__init__.py b/OpenOversight/app/__init__.py index 34cf8abc6..4538914a5 100644 --- a/OpenOversight/app/__init__.py +++ b/OpenOversight/app/__init__.py @@ -48,7 +48,11 @@ def create_app(config_name="default"): # This allows the application to run without creating an email client if it is # in testing or dev mode and the service account file is empty. service_account_file_size = os.path.getsize(SERVICE_ACCOUNT_FILE) - EmailClient(dev=app.debug and service_account_file_size == 0, testing=app.testing) + EmailClient( + config=app.config, + dev=app.debug and service_account_file_size == 0, + testing=app.testing, + ) limiter.init_app(app) login_manager.init_app(app) sitemap.init_app(app) From 2a5113fd0d4bf1d1b8292c2924989bbab18f33fb Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Mon, 10 Jul 2023 13:24:15 -0500 Subject: [PATCH 04/29] Update views.py --- OpenOversight/app/main/views.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/OpenOversight/app/main/views.py b/OpenOversight/app/main/views.py index 31ad17f6c..8972cb5fe 100644 --- a/OpenOversight/app/main/views.py +++ b/OpenOversight/app/main/views.py @@ -147,7 +147,7 @@ def get_officer(): jsloads = ["js/find_officer.js"] form = FindOfficerForm() - depts_dict = [dept_choice.toCustomDict() for dept_choice in dept_choices()] + departments_dict = [dept_choice.toCustomDict() for dept_choice in dept_choices()] if getattr(current_user, "dept_pref_rel", None): set_dynamic_default(form.dept, current_user.dept_pref_rel) @@ -177,7 +177,7 @@ def get_officer(): else: current_app.logger.info(form.errors) return render_template( - "input_find_officer.html", form=form, depts_dict=depts_dict, jsloads=jsloads + "input_find_officer.html", form=form, depts_dict=departments_dict, jsloads=jsloads ) From b35bdb5443665ebf44b637f9df2475fb39c0ed95 Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Mon, 10 Jul 2023 13:42:07 -0500 Subject: [PATCH 05/29] Update views.py --- OpenOversight/app/main/views.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/OpenOversight/app/main/views.py b/OpenOversight/app/main/views.py index 8972cb5fe..b9fa0919f 100644 --- a/OpenOversight/app/main/views.py +++ b/OpenOversight/app/main/views.py @@ -177,7 +177,10 @@ def get_officer(): else: current_app.logger.info(form.errors) return render_template( - "input_find_officer.html", form=form, depts_dict=departments_dict, jsloads=jsloads + "input_find_officer.html", + form=form, + depts_dict=departments_dict, + jsloads=jsloads, ) From e368c25aae2ff7490142d22f3b5facd2619a6862 Mon Sep 17 00:00:00 2001 From: michplunkett <5885605+michplunkett@users.noreply.github.com> Date: Mon, 10 Jul 2023 13:45:08 -0500 Subject: [PATCH 06/29] Update list_officer.html --- OpenOversight/app/templates/list_officer.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/OpenOversight/app/templates/list_officer.html b/OpenOversight/app/templates/list_officer.html index 9bdaad382..b2c745488 100644 --- a/OpenOversight/app/templates/list_officer.html +++ b/OpenOversight/app/templates/list_officer.html @@ -163,7 +163,7 @@