Skip to content

Commit cc21b42

Browse files
authored
Merge pull request #5960 from freelawproject/5154-feat-add-support-to-purchase-acms-dockets
feat(recap): Enhances appellate docket purchase to support ACMS cases
2 parents 7a41487 + 7e05d32 commit cc21b42

File tree

6 files changed

+350
-24
lines changed

6 files changed

+350
-24
lines changed

cl/corpus_importer/utils.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,20 @@ async def ais_appellate_court(court_id: str) -> bool:
150150
return await appellate_court_ids.filter(pk=court_id).aexists()
151151

152152

153+
def should_check_acms_court(court_id: str) -> bool:
154+
"""
155+
Checks whether the given court_id should be checked using ACMS-specific logic.
156+
157+
This helper is used to identify courts that require special handling,
158+
currently limited to a known set of appellate courts.
159+
160+
:param court_id: The unique identifier of the court.
161+
162+
:return: True if the court_id is one that uses ACMS; False otherwise.
163+
"""
164+
return court_id in ["ca2", "ca9"]
165+
166+
153167
def get_start_of_quarter(d: date | None = None) -> date:
154168
"""Get the start date of the calendar quarter requested
155169

cl/recap/mergers.py

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
# Code for merging PACER content into the DB
2+
import json
23
import logging
34
import re
45
from copy import deepcopy
@@ -1584,9 +1585,21 @@ def merge_pacer_docket_into_cl_docket(
15841585
UPLOAD_TYPE.APPELLATE_DOCKET if appellate else UPLOAD_TYPE.DOCKET
15851586
)
15861587
pacer_file = PacerHtmlFiles(content_object=d, upload_type=upload_type)
1588+
1589+
# Determine how to store the report data.
1590+
# Most PACER reports include a raw HTML response and set the `response`
1591+
# attribute. However, ACMS reports typically construct the data from a
1592+
# series of API calls, and do not include a single HTML response. In those
1593+
# cases, we store the data as JSON instead.
1594+
pacer_file_name = "docket.html" if report.response else "docket.json"
1595+
pacer_file_content = (
1596+
report.response.text.encode()
1597+
if report.response
1598+
else json.dumps(report.data, default=str).encode()
1599+
)
15871600
pacer_file.filepath.save(
1588-
"docket.html", # We only care about the ext w/S3PrivateUUIDStorageTest
1589-
ContentFile(report.response.text.encode()),
1601+
pacer_file_name, # We only care about the ext w/S3PrivateUUIDStorageTest
1602+
ContentFile(pacer_file_content),
15901603
)
15911604

15921605
# Merge parties before adding docket entries, so they can access parties'

cl/recap/tasks.py

Lines changed: 29 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from juriscraper.lib.string_utils import CaseNameTweaker, harmonize
2828
from juriscraper.pacer import (
2929
ACMSAttachmentPage,
30+
AcmsCaseSearch,
3031
ACMSDocketReport,
3132
AppellateDocketReport,
3233
CaseQuery,
@@ -65,6 +66,7 @@
6566
is_bankruptcy_court,
6667
is_long_appellate_document_number,
6768
mark_ia_upload_needed,
69+
should_check_acms_court,
6870
)
6971
from cl.custom_filters.templatetags.text_filters import oxford_join
7072
from cl.lib.filesizes import convert_size_to_bytes
@@ -110,6 +112,7 @@
110112
find_subdocket_pdf_rds_from_data,
111113
get_court_id_from_fetch_queue,
112114
get_main_rds,
115+
sort_acms_docket_entries,
113116
)
114117
from cl.scrapers.tasks import (
115118
extract_recap_pdf,
@@ -1493,17 +1496,7 @@ async def process_recap_acms_docket(pk):
14931496
await sync_to_async(add_parties_and_attorneys)(d, data["parties"])
14941497

14951498
# Sort docket entries to ensure consistent ordering
1496-
# The primary sort is by 'date_filed', followed by 'document_number' (nulls
1497-
# last for a given date). This approach aligns the order with how docket
1498-
# reports are typically displayed.
1499-
data["docket_entries"] = sorted(
1500-
data["docket_entries"],
1501-
key=lambda d: (
1502-
d["date_filed"],
1503-
d["document_number"] is None,
1504-
d["document_number"],
1505-
),
1506-
)
1499+
data["docket_entries"] = sort_acms_docket_entries(data["docket_entries"])
15071500
des_returned, rds_created, content_updated = await add_docket_entries(
15081501
d, data["docket_entries"]
15091502
)
@@ -2348,7 +2341,7 @@ def create_or_update_docket_data_from_fetch(
23482341
fq: PacerFetchQueue,
23492342
court_id: str,
23502343
pacer_case_id: str | None,
2351-
report: DocketReport | AppellateDocketReport,
2344+
report: DocketReport | AppellateDocketReport | ACMSDocketReport,
23522345
docket_data: dict[str, Any],
23532346
) -> dict[str, str | bool]:
23542347
"""Creates or updates docket data in the database from fetched data.
@@ -2420,12 +2413,34 @@ def purchase_appellate_docket_by_docket_number(
24202413
:param fq: The PacerFetchQueue object
24212414
:return: a dict with information about the docket and the new data
24222415
"""
2423-
report = AppellateDocketReport(map_cl_to_pacer_id(court_id), session)
2424-
report.query(docket_number, **kwargs)
2416+
acms_case_id = None
2417+
2418+
if should_check_acms_court(court_id):
2419+
acms_search = AcmsCaseSearch(court_id=court_id, pacer_session=session)
2420+
acms_search.query(docket_number)
2421+
acms_case_id = (
2422+
acms_search.data["pcx_caseid"] if acms_search.data else None
2423+
)
2424+
2425+
pacer_court_id = map_cl_to_pacer_id(court_id)
2426+
report_class = ACMSDocketReport if acms_case_id else AppellateDocketReport
2427+
report = report_class(pacer_court_id, session)
2428+
2429+
if acms_case_id:
2430+
# ACMSDocketReport only accepts the case ID; filters are not currently
2431+
# supported for ACMS docket reports.
2432+
report.query(acms_case_id)
2433+
else:
2434+
report.query(docket_number, **kwargs)
24252435

24262436
docket_data = report.data
24272437
if not docket_data:
24282438
raise ParsingException("No data found in docket report.")
2439+
2440+
if acms_case_id:
2441+
docket_data["docket_entries"] = sort_acms_docket_entries(
2442+
docket_data["docket_entries"]
2443+
)
24292444
return create_or_update_docket_data_from_fetch(
24302445
fq, court_id, None, report, docket_data
24312446
)

0 commit comments

Comments
 (0)