diff --git a/cl/citations/match_citations_queries.py b/cl/citations/match_citations_queries.py index 720a8e8510..0a431daa3d 100644 --- a/cl/citations/match_citations_queries.py +++ b/cl/citations/match_citations_queries.py @@ -36,9 +36,7 @@ def fetch_citations(search_query: Search, fields=None) -> list[Hit]: citation_hits = [] search_query = search_query.sort("id") # Only retrieve fields required for the lookup. - search_query = search_query.source( - includes=fields - ) + search_query = search_query.source(includes=fields) # Citation resolution aims for a single match. Setting up a size of 2 is # enough to determine if there is more than one match. search_query = search_query.extra(size=2) @@ -223,14 +221,20 @@ def es_search_db_for_full_citation( # We didn't get an exact match on the volume/reporter/page. Perhaps # it's a pincite. Find closest citations filtering by volume and # reporter and excluding self cites. - partial_citation_str = " ".join([full_citation.groups["volume"], full_citation.groups["reporter"]]) - filters = [Q( - "match_phrase", - **{"citation.exact": partial_citation_str}, - )] + partial_citation_str = " ".join( + [full_citation.groups["volume"], full_citation.groups["reporter"]] + ) + filters = [ + Q( + "match_phrase", + **{"citation.exact": partial_citation_str}, + ) + ] query = Q("bool", must_not=must_not, filter=filters) citations_query = search_query.query(query) - results = fetch_citations(citations_query, fields=["id", "cluster_id", "citation", "text"]) + results = fetch_citations( + citations_query, fields=["id", "cluster_id", "citation", "text"] + ) closest_opinion_clusters = [] # Create a temporal item and add it to the values list (cluster_id, @@ -241,10 +245,16 @@ def es_search_db_for_full_citation( for result in results: # Get the citations from OpinionDocument that matched the partial # citation - valid_citations = [get_citations(citation)[0] for citation in result["citation"] if partial_citation_str in citation and get_citations(citation)] + valid_citations = [ + get_citations(citation)[0] + for citation in result["citation"] + if partial_citation_str in citation and get_citations(citation) + ] for valid_citation in valid_citations: - closest_opinion_clusters.append((result["cluster_id"], valid_citation.groups["page"])) + closest_opinion_clusters.append( + (result["cluster_id"], valid_citation.groups["page"]) + ) if len(closest_opinion_clusters) > 1: # Order by page number @@ -258,13 +268,23 @@ def es_search_db_for_full_citation( # if the position is greater than 0, then the previous item in # the list is the closest citation, we get the cluster id of the # previous item - possible_cluster_id_matched = sort_possible_matches[citation_item_position - 1][0] + possible_cluster_id_matched = sort_possible_matches[ + citation_item_position - 1 + ][0] # We filter the results list to get the possible match # OpinionDocument - filtered_results = [hit for hit in results if hit.cluster_id == possible_cluster_id_matched] - - if len(filtered_results) == 1 and f"*{full_citation.groups["page"]}" in filtered_results[0]["text"]: + filtered_results = [ + hit + for hit in results + if hit.cluster_id == possible_cluster_id_matched + ] + + if ( + len(filtered_results) == 1 + and f"*{full_citation.groups["page"]}" + in filtered_results[0]["text"] + ): # Check if the page number is in the opinion text, currently # we only look for this format: *page_number return [filtered_results[0]], True diff --git a/cl/people_db/migrations/0019_alter_person_religion_alter_personevent_religion.py b/cl/people_db/migrations/0019_alter_person_religion_alter_personevent_religion.py new file mode 100644 index 0000000000..a3625787dd --- /dev/null +++ b/cl/people_db/migrations/0019_alter_person_religion_alter_personevent_religion.py @@ -0,0 +1,64 @@ +# Generated by Django 5.1.5 on 2025-02-05 03:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ( + "people_db", + "0018_alter_person_religion_alter_personevent_religion_and_more", + ), + ] + + operations = [ + migrations.AlterField( + model_name="person", + name="religion", + field=models.CharField( + blank=True, + choices=[ + ("ca", "Catholic"), + ("pr", "Protestant"), + ("je", "Jewish"), + ("mu", "Muslim"), + ("at", "Atheist"), + ("ag", "Agnostic"), + ("mo", "Mormon"), + ("bu", "Buddhist"), + ("hi", "Hindu"), + ("ep", "Episcopalian"), + ("ro", "Roman Catholic"), + ("me", "Methodist"), + ("pe", "Presbyterian"), + ], + help_text="The religion of a person", + max_length=30, + ), + ), + migrations.AlterField( + model_name="personevent", + name="religion", + field=models.CharField( + blank=True, + choices=[ + ("ca", "Catholic"), + ("pr", "Protestant"), + ("je", "Jewish"), + ("mu", "Muslim"), + ("at", "Atheist"), + ("ag", "Agnostic"), + ("mo", "Mormon"), + ("bu", "Buddhist"), + ("hi", "Hindu"), + ("ep", "Episcopalian"), + ("ro", "Roman Catholic"), + ("me", "Methodist"), + ("pe", "Presbyterian"), + ], + help_text="The religion of a person", + max_length=30, + ), + ), + ] diff --git a/cl/people_db/migrations/0019_alter_person_religion_alter_personevent_religion.sql b/cl/people_db/migrations/0019_alter_person_religion_alter_personevent_religion.sql new file mode 100644 index 0000000000..be388a96fb --- /dev/null +++ b/cl/people_db/migrations/0019_alter_person_religion_alter_personevent_religion.sql @@ -0,0 +1,10 @@ +BEGIN; +-- +-- Alter field religion on person +-- +-- (no-op) +-- +-- Alter field religion on personevent +-- +-- (no-op) +COMMIT; diff --git a/cl/people_db/migrations/0020_alter_person_religion_alter_personevent_religion_and_more.py b/cl/people_db/migrations/0020_alter_person_religion_alter_personevent_religion_and_more.py new file mode 100644 index 0000000000..f35f473922 --- /dev/null +++ b/cl/people_db/migrations/0020_alter_person_religion_alter_personevent_religion_and_more.py @@ -0,0 +1,295 @@ +# Generated by Django 5.1.5 on 2025-02-05 19:53 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("people_db", "0019_alter_person_religion_alter_personevent_religion"), + ] + + operations = [ + migrations.AlterField( + model_name="person", + name="religion", + field=models.CharField( + blank=True, + choices=[ + ("ca", "Catholic"), + ("pr", "Protestant"), + ("je", "Jewish"), + ("mu", "Muslim"), + ("at", "Atheist"), + ("ag", "Agnostic"), + ("mo", "Mormon"), + ("bu", "Buddhist"), + ("hi", "Hindu"), + ("ep", "Episcopalian"), + ("ro", "Roman Catholic"), + ("me", "Methodist"), + ("pe", "Presbyterian"), + ("un", "Unitarian"), + ], + help_text="The religion of a person", + max_length=30, + ), + ), + migrations.AlterField( + model_name="personevent", + name="religion", + field=models.CharField( + blank=True, + choices=[ + ("ca", "Catholic"), + ("pr", "Protestant"), + ("je", "Jewish"), + ("mu", "Muslim"), + ("at", "Atheist"), + ("ag", "Agnostic"), + ("mo", "Mormon"), + ("bu", "Buddhist"), + ("hi", "Hindu"), + ("ep", "Episcopalian"), + ("ro", "Roman Catholic"), + ("me", "Methodist"), + ("pe", "Presbyterian"), + ("un", "Unitarian"), + ], + help_text="The religion of a person", + max_length=30, + ), + ), + migrations.AlterField( + model_name="position", + name="position_type", + field=models.CharField( + blank=True, + choices=[ + ( + "Judge", + [ + ("jud", "Judge"), + ("jus", "Justice"), + ("ad-law-jud", "Administrative Law Judge"), + ("act-jud", "Acting Judge"), + ("act-jus", "Acting Justice"), + ("act-pres-jud", "Acting Presiding Judge"), + ( + "act-c-admin-jus", + "Acting Chief Administrative Justice", + ), + ("ass-jud", "Associate Judge"), + ("ass-jus", "Associate Justice"), + ("ass-c-jud", "Associate Chief Judge"), + ("ass-pres-jud", "Associate Presiding Judge"), + ("asst-pres-jud", "Assistant Presiding Judge"), + ("c-jud", "Chief Judge"), + ("c-jus", "Chief Justice"), + ("c-spec-m", "Chief Special Master"), + ("c-admin-jus", "Chief Administrative Justice"), + ("c-spec-tr-jud", "Chief Special Trial Judge"), + ("pres-jud", "Presiding Judge"), + ("pres-jus", "Presiding Justice"), + ("sup-jud", "Supervising Judge"), + ( + "ad-pres-jus", + "Administrative Presiding Justice", + ), + ("com", "Commissioner"), + ("com-dep", "Deputy Commissioner"), + ("jud-pt", "Judge Pro Tem"), + ("jus-pt", "Justice Pro Tem"), + ("ref-jud-tr", "Judge Trial Referee"), + ("ref-off", "Official Referee"), + ("ref-state-trial", "State Trial Referee"), + ("ret-act-jus", "Active Retired Justice"), + ("ret-ass-jud", "Retired Associate Judge"), + ("ret-c-jud", "Retired Chief Judge"), + ("ret-jus", "Retired Justice"), + ("ret-senior-jud", "Senior Judge"), + ("mag", "Magistrate"), + ("c-mag", "Chief Magistrate"), + ("pres-mag", "Presiding Magistrate"), + ("mag-pt", "Magistrate Pro Tem"), + ("mag-rc", "Magistrate (Recalled)"), + ("mag-part-time", "Magistrate (Part-Time)"), + ("spec-chair", "Special Chairman"), + ("spec-jud", "Special Judge"), + ("spec-m", "Special Master"), + ( + "spec-scjcbc", + "Special Superior Court Judge for Complex Business Cases", + ), + ("spec-tr-jud", "Special Trial Judge"), + ("chair", "Chairman"), + ("chan", "Chancellor"), + ("presi-jud", "President"), + ("res-jud", "Reserve Judge"), + ("trial-jud", "Trial Judge"), + ("vice-chan", "Vice Chancellor"), + ("vice-cj", "Vice Chief Judge"), + ], + ), + ( + "Attorney General", + [ + ("att-gen", "Attorney General"), + ("att-gen-ass", "Assistant Attorney General"), + ( + "att-gen-ass-spec", + "Special Assistant Attorney General", + ), + ("sen-counsel", "Senior Counsel"), + ("dep-sol-gen", "Deputy Solicitor General"), + ], + ), + ( + "Appointing Authority", + [ + ("pres", "President of the United States"), + ("gov", "Governor"), + ("mayor", "Mayor"), + ], + ), + ( + "Clerkships", + [ + ("clerk", "Clerk"), + ("clerk-chief-dep", "Chief Deputy Clerk"), + ("staff-atty", "Staff Attorney"), + ], + ), + ("prof", "Professor"), + ("adj-prof", "Adjunct Professor"), + ("prac", "Practitioner"), + ("pros", "Prosecutor"), + ("pub-def", "Public Defender"), + ("da", "District Attorney"), + ("ada", "Assistant District Attorney"), + ("legis", "Legislator"), + ("sen", "Senator"), + ("state-sen", "State Senator"), + ], + help_text="If this is a judicial position, this indicates the role the person had. This field may be blank if job_title is complete instead.", + max_length=20, + null=True, + ), + ), + migrations.AlterField( + model_name="positionevent", + name="position_type", + field=models.CharField( + blank=True, + choices=[ + ( + "Judge", + [ + ("jud", "Judge"), + ("jus", "Justice"), + ("ad-law-jud", "Administrative Law Judge"), + ("act-jud", "Acting Judge"), + ("act-jus", "Acting Justice"), + ("act-pres-jud", "Acting Presiding Judge"), + ( + "act-c-admin-jus", + "Acting Chief Administrative Justice", + ), + ("ass-jud", "Associate Judge"), + ("ass-jus", "Associate Justice"), + ("ass-c-jud", "Associate Chief Judge"), + ("ass-pres-jud", "Associate Presiding Judge"), + ("asst-pres-jud", "Assistant Presiding Judge"), + ("c-jud", "Chief Judge"), + ("c-jus", "Chief Justice"), + ("c-spec-m", "Chief Special Master"), + ("c-admin-jus", "Chief Administrative Justice"), + ("c-spec-tr-jud", "Chief Special Trial Judge"), + ("pres-jud", "Presiding Judge"), + ("pres-jus", "Presiding Justice"), + ("sup-jud", "Supervising Judge"), + ( + "ad-pres-jus", + "Administrative Presiding Justice", + ), + ("com", "Commissioner"), + ("com-dep", "Deputy Commissioner"), + ("jud-pt", "Judge Pro Tem"), + ("jus-pt", "Justice Pro Tem"), + ("ref-jud-tr", "Judge Trial Referee"), + ("ref-off", "Official Referee"), + ("ref-state-trial", "State Trial Referee"), + ("ret-act-jus", "Active Retired Justice"), + ("ret-ass-jud", "Retired Associate Judge"), + ("ret-c-jud", "Retired Chief Judge"), + ("ret-jus", "Retired Justice"), + ("ret-senior-jud", "Senior Judge"), + ("mag", "Magistrate"), + ("c-mag", "Chief Magistrate"), + ("pres-mag", "Presiding Magistrate"), + ("mag-pt", "Magistrate Pro Tem"), + ("mag-rc", "Magistrate (Recalled)"), + ("mag-part-time", "Magistrate (Part-Time)"), + ("spec-chair", "Special Chairman"), + ("spec-jud", "Special Judge"), + ("spec-m", "Special Master"), + ( + "spec-scjcbc", + "Special Superior Court Judge for Complex Business Cases", + ), + ("spec-tr-jud", "Special Trial Judge"), + ("chair", "Chairman"), + ("chan", "Chancellor"), + ("presi-jud", "President"), + ("res-jud", "Reserve Judge"), + ("trial-jud", "Trial Judge"), + ("vice-chan", "Vice Chancellor"), + ("vice-cj", "Vice Chief Judge"), + ], + ), + ( + "Attorney General", + [ + ("att-gen", "Attorney General"), + ("att-gen-ass", "Assistant Attorney General"), + ( + "att-gen-ass-spec", + "Special Assistant Attorney General", + ), + ("sen-counsel", "Senior Counsel"), + ("dep-sol-gen", "Deputy Solicitor General"), + ], + ), + ( + "Appointing Authority", + [ + ("pres", "President of the United States"), + ("gov", "Governor"), + ("mayor", "Mayor"), + ], + ), + ( + "Clerkships", + [ + ("clerk", "Clerk"), + ("clerk-chief-dep", "Chief Deputy Clerk"), + ("staff-atty", "Staff Attorney"), + ], + ), + ("prof", "Professor"), + ("adj-prof", "Adjunct Professor"), + ("prac", "Practitioner"), + ("pros", "Prosecutor"), + ("pub-def", "Public Defender"), + ("da", "District Attorney"), + ("ada", "Assistant District Attorney"), + ("legis", "Legislator"), + ("sen", "Senator"), + ("state-sen", "State Senator"), + ], + help_text="If this is a judicial position, this indicates the role the person had. This field may be blank if job_title is complete instead.", + max_length=20, + null=True, + ), + ), + ] diff --git a/cl/people_db/migrations/0020_alter_person_religion_alter_personevent_religion_and_more_noop.sql b/cl/people_db/migrations/0020_alter_person_religion_alter_personevent_religion_and_more_noop.sql new file mode 100644 index 0000000000..c698d310cd --- /dev/null +++ b/cl/people_db/migrations/0020_alter_person_religion_alter_personevent_religion_and_more_noop.sql @@ -0,0 +1,18 @@ +BEGIN; +-- +-- Alter field religion on person +-- +-- (no-op) +-- +-- Alter field religion on personevent +-- +-- (no-op) +-- +-- Alter field position_type on position +-- +-- (no-op) +-- +-- Alter field position_type on positionevent +-- +-- (no-op) +COMMIT; diff --git a/cl/people_db/models.py b/cl/people_db/models.py index 2454152dbd..d00105d4ef 100644 --- a/cl/people_db/models.py +++ b/cl/people_db/models.py @@ -68,7 +68,8 @@ class Person(AbstractDateTimeModel): ("ep", "Episcopalian"), ("ro", "Roman Catholic"), ("me", "Methodist"), - ("pr", "Presbyterian"), + ("pe", "Presbyterian"), + ("un", "Unitarian"), ) race = models.ManyToManyField( "Race", @@ -343,6 +344,7 @@ class Position(AbstractDateTimeModel): CHIEF_JUSTICE = "c-jus" CHIEF_SPECIAL_MASTER = "c-spec-m" CHIEF_ADMINISTRATIVE_JUSTICE = "c-admin-jus" + CHIEF_SPECIAL_TRIAL_JUDGE = "c-spec-tr-jud" PRESIDING_JUDGE = "pres-jud" PRESIDING_JUSTICE = "pres-jus" SUPERVISING_JUDGE = "sup-jud" @@ -434,6 +436,7 @@ class Position(AbstractDateTimeModel): (CHIEF_JUSTICE, "Chief Justice"), (CHIEF_SPECIAL_MASTER, "Chief Special Master"), (CHIEF_ADMINISTRATIVE_JUSTICE, "Chief Administrative Justice"), + (CHIEF_SPECIAL_TRIAL_JUDGE, "Chief Special Trial Judge"), (PRESIDING_JUDGE, "Presiding Judge"), (PRESIDING_JUSTICE, "Presiding Justice"), (SUPERVISING_JUDGE, "Supervising Judge"),