Skip to content

Commit

Permalink
Merge branch 'main' into scrape_citations_command
Browse files Browse the repository at this point in the history
  • Loading branch information
mlissner committed Aug 21, 2024
2 parents ace253e + 0ecfca5 commit b91fbf5
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 20 deletions.
49 changes: 43 additions & 6 deletions cl/lib/elasticsearch_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@
from django.conf import settings
from django.core.cache import caches
from django.core.paginator import EmptyPage, Page
from django.db.models import Case
from django.db.models import Case, CharField
from django.db.models import Q as QObject
from django.db.models import QuerySet, TextField, When
from django.db.models import QuerySet, TextField, Value, When
from django.db.models.functions import Substr
from django.forms.boundfield import BoundField
from django.http import HttpRequest
Expand Down Expand Up @@ -1810,6 +1810,11 @@ def merge_unavailable_fields_on_parent_document(
"pk", flat=True
)
)
bankruptcy_ids = (
Court.federal_courts.bankruptcy_pacer_courts().values_list(
"pk", flat=True
)
)
initial_complaints = (
RECAPDocument.objects.filter(
QObject(
Expand Down Expand Up @@ -1845,26 +1850,58 @@ def merge_unavailable_fields_on_parent_document(
"docket_entry__docket__court__jurisdiction",
"docket_entry__docket__court_id",
)
.annotate(
court_type=Case(
When(
docket_entry__docket__court_id__in=appellate_court_ids,
then=Value("appellate"),
),
When(
docket_entry__docket__court_id__in=bankruptcy_ids,
then=Value("bankruptcy"),
),
default=Value("district"),
output_field=CharField(),
)
)
)

initial_complaints_in_page = {}
for initial_complaint in initial_complaints:
if initial_complaint.has_valid_pdf:
# Initial complaint/petition/appeal available
text_button = {
"appellate": "Notice of Appeal",
"bankruptcy": "Initial Petition",
}.get(initial_complaint.court_type, "Initial Complaint")
initial_complaints_in_page[
initial_complaint.docket_entry.docket_id
] = (initial_complaint.get_absolute_url(), None)
] = (
initial_complaint.get_absolute_url(),
None,
text_button,
)
else:
# Initial complaint/petition/appeal not available. Buy button.
buy_text_button = {
"appellate": "Buy Notice of Appeal",
"bankruptcy": "Buy Initial Petition",
}.get(
initial_complaint.court_type, "Buy Initial Complaint"
)
initial_complaints_in_page[
initial_complaint.docket_entry.docket_id
] = (None, initial_complaint.pacer_url)
] = (None, initial_complaint.pacer_url, buy_text_button)

for result in results:
complaint_url, buy_complaint_url = (
complaint_url, buy_complaint_url, text_button = (
initial_complaints_in_page.get(
result.docket_id, (None, None)
result.docket_id, (None, None, "")
)
)
result["initial_complaint_url"] = complaint_url
result["buy_initial_complaint_url"] = buy_complaint_url
result["initial_complaint_text"] = text_button

case SEARCH_TYPES.OPINION if request_type == "v4" and not highlight:
# Retrieves the Opinion plain_text from the DB to fill the snippet
Expand Down
4 changes: 2 additions & 2 deletions cl/search/templates/includes/search_result.html
Original file line number Diff line number Diff line change
Expand Up @@ -209,11 +209,11 @@ <h4>
<div class="col-md-offset-half">
{% if result.initial_complaint_url %}
<a href="{{ result.initial_complaint_url }}" class="initial-complaint btn-primary btn">
Initial Complaint
{{ result.initial_complaint_text }}
</a>
{% elif result.buy_initial_complaint_url %}
<a href="{{ result.buy_initial_complaint_url }}" rel="nofollow" target="_blank" class="initial-complaint btn-primary btn">
Buy Initial Complaint
{{ result.initial_complaint_text }}
</a>
{% endif %}
{% if result.child_remaining %}
Expand Down
132 changes: 121 additions & 11 deletions cl/search/tests/tests_es_recap.py
Original file line number Diff line number Diff line change
Expand Up @@ -2254,13 +2254,16 @@ def test_initial_complaint_button(self) -> None:
"""Confirm the initial complaint button is properly shown on different
scenarios"""

district_court = CourtFactory(id="cand", jurisdiction="FD")

dockets_to_remove = []
# Add dockets with no documents
with self.captureOnCommitCallbacks(execute=True):

# District document initial complaint available
de_1 = DocketEntryWithParentsFactory(
docket=DocketFactory(
court=self.court,
court=district_court,
case_name="Lorem District vs Complaint Available",
docket_number="1:21-bk-1234",
source=Docket.RECAP,
Expand All @@ -2269,6 +2272,7 @@ def test_initial_complaint_button(self) -> None:
date_filed=datetime.date(2015, 8, 19),
description="MOTION for Leave to File Amicus Curiae Lorem Served",
)
dockets_to_remove.append(de_1.docket)
sample_file = SimpleUploadedFile("recap_filename.pdf", b"file")
initial_complaint_1 = RECAPDocumentFactory(
docket_entry=de_1,
Expand All @@ -2292,7 +2296,7 @@ def test_initial_complaint_button(self) -> None:
# District document initial complaint not available
de_2 = DocketEntryWithParentsFactory(
docket=DocketFactory(
court=self.court,
court=district_court,
case_name="Lorem District vs Complaint Not Available",
docket_number="1:21-bk-1235",
source=Docket.RECAP,
Expand All @@ -2301,6 +2305,7 @@ def test_initial_complaint_button(self) -> None:
date_filed=datetime.date(2015, 8, 19),
description="MOTION for Leave to File Amicus Curiae Lorem Served",
)
dockets_to_remove.append(de_2.docket)
initial_complaint_2 = RECAPDocumentFactory(
docket_entry=de_2,
document_number="1",
Expand Down Expand Up @@ -2330,6 +2335,7 @@ def test_initial_complaint_button(self) -> None:
date_filed=datetime.date(2015, 8, 19),
description="MOTION for Leave to File Amicus Curiae Lorem Served",
)
dockets_to_remove.append(de_3.docket)
initial_complaint_3 = RECAPDocumentFactory(
docket_entry=de_3,
document_number="1",
Expand All @@ -2349,6 +2355,7 @@ def test_initial_complaint_button(self) -> None:
date_filed=datetime.date(2015, 8, 19),
description="MOTION for Leave to File Amicus Curiae Lorem Served",
)
dockets_to_remove.append(de_4.docket)
sample_file = SimpleUploadedFile("recap_filename.pdf", b"file")
initial_complaint_4 = RECAPDocumentFactory(
docket_entry=de_4,
Expand All @@ -2360,13 +2367,79 @@ def test_initial_complaint_button(self) -> None:
pacer_doc_id="7654321",
)

# Appellate document notice of appeal not available
de_5 = DocketEntryWithParentsFactory(
docket=DocketFactory(
court=self.court_2,
case_name="Lorem Appellate vs Notice of appeal not Available",
docket_number="1:21-bk-1239",
source=Docket.RECAP,
),
entry_number=1,
date_filed=datetime.date(2015, 8, 19),
description="MOTION for Leave to File Amicus Curiae Lorem Served",
)
dockets_to_remove.append(de_5.docket)
initial_complaint_5 = RECAPDocumentFactory(
docket_entry=de_5,
document_number="1",
attachment_number=1,
document_type=RECAPDocument.ATTACHMENT,
is_available=False,
pacer_doc_id="765425",
)

# No DocketEntry for the initial complaint available
empty_docket = DocketFactory(
court=self.court,
court=district_court,
case_name="Lorem No Initial Complaint Entry",
docket_number="1:21-bk-1237",
source=Docket.RECAP,
)
dockets_to_remove.append(empty_docket)
# Bankruptcy document initial petition available
de_6 = DocketEntryWithParentsFactory(
docket=DocketFactory(
court=self.court,
case_name="Lorem Bankruptcy vs Petition Available",
docket_number="1:21-bk-1240",
source=Docket.RECAP,
),
entry_number=1,
date_filed=datetime.date(2015, 8, 19),
description="MOTION for Leave to File Amicus Curiae Lorem Served",
)
dockets_to_remove.append(de_6.docket)
sample_file = SimpleUploadedFile("recap_filename.pdf", b"file")
initial_complaint_6 = RECAPDocumentFactory(
docket_entry=de_6,
document_number="1",
document_type=RECAPDocument.PACER_DOCUMENT,
is_available=True,
filepath_local=sample_file,
pacer_doc_id="12345875",
)

# Bankruptcy document initial petition not available
de_7 = DocketEntryWithParentsFactory(
docket=DocketFactory(
court=self.court,
case_name="Lorem Bankruptcy vs Petition Not Available",
docket_number="1:21-bk-1240",
source=Docket.RECAP,
),
entry_number=1,
date_filed=datetime.date(2015, 8, 19),
description="MOTION for Leave to File Amicus Curiae Lorem Served",
)
dockets_to_remove.append(de_7.docket)
initial_complaint_7 = RECAPDocumentFactory(
docket_entry=de_7,
document_number="1",
document_type=RECAPDocument.PACER_DOCUMENT,
is_available=False,
pacer_doc_id="35345875",
)

# District document initial complaint available
cd = {
Expand All @@ -2389,10 +2462,10 @@ def test_initial_complaint_button(self) -> None:
cd, 1, "Complaint Not available"
)
button_url, button_text = self._parse_initial_complaint_button(r)
self.assertEqual("Buy Initial Complaint", button_text, msg="Error 1")
self.assertEqual("Buy Initial Complaint", button_text)
self.assertEqual(initial_complaint_2.pacer_url, button_url)

# Appellate document initial complaint available
# Appellate notice of appeal available
cd = {
"type": SEARCH_TYPES.RECAP,
"q": '"Lorem Appellate vs Complaint Available"',
Expand All @@ -2401,7 +2474,7 @@ def test_initial_complaint_button(self) -> None:
cd, 1, "Complaint Appellate available"
)
button_url, button_text = self._parse_initial_complaint_button(r)
self.assertEqual("Initial Complaint", button_text)
self.assertEqual("Notice of Appeal", button_text)
self.assertEqual(initial_complaint_4.get_absolute_url(), button_url)

# No docket entry is available for the initial complaint. No button is shown.
Expand Down Expand Up @@ -2429,11 +2502,48 @@ def test_initial_complaint_button(self) -> None:
self.assertIsNone(button_text)
self.assertIsNone(button_url)

de_1.docket.delete()
de_2.docket.delete()
de_3.docket.delete()
de_4.docket.delete()
empty_docket.delete()
# Appellate notice of appeal not available. Button Buy Notice of appeal
cd = {
"type": SEARCH_TYPES.RECAP,
"q": '"Lorem Appellate vs Notice of appeal not Available"',
}
r = async_to_sync(self._test_article_count)(
cd, 1, "Complaint Appellate available"
)
button_url, button_text = self._parse_initial_complaint_button(r)
self.assertEqual("Buy Notice of Appeal", button_text)
self.assertEqual(initial_complaint_5.pacer_url, button_url)

"Lorem Bankruptcy vs Petition Available"

# Bankruptcy document initial petition available
cd = {
"type": SEARCH_TYPES.RECAP,
"q": '"Lorem Bankruptcy vs Petition Available"',
}
r = async_to_sync(self._test_article_count)(
cd, 1, "Complaint available"
)
button_url, button_text = self._parse_initial_complaint_button(r)
self.assertEqual("Initial Petition", button_text)
self.assertEqual(initial_complaint_6.get_absolute_url(), button_url)

# Bankruptcy document initial petition not available. Show Buy button.
cd = {
"type": SEARCH_TYPES.RECAP,
"q": '"Lorem Bankruptcy vs Petition Not Available"',
}
r = async_to_sync(self._test_article_count)(
cd, 1, "Complaint Not available"
)
button_url, button_text = self._parse_initial_complaint_button(r)
self.assertEqual(
"Buy Initial Petition", button_text, msg="Failed here..."
)
self.assertEqual(initial_complaint_7.pacer_url, button_url)

for docket in dockets_to_remove:
docket.delete()


class RECAPSearchAPICommonTests(RECAPSearchTestCase):
Expand Down
2 changes: 1 addition & 1 deletion scripts/make_bulk_data.sh
Original file line number Diff line number Diff line change
Expand Up @@ -418,7 +418,7 @@ declare -a lst="$group"
cat >> "$OUT" <<- EOF
echo "Loading ${lst[2]} to database"
psql --command \
"COPY public.${lst[0]} ${lst[1]} FROM '\$BULK_DIR/${lst[2]}' WITH (FORMAT csv, ENCODING utf8, QUOTE \'\`\', HEADER)" \
"\COPY public.${lst[0]} ${lst[1]} FROM '\$BULK_DIR/${lst[2]}' WITH (FORMAT csv, ENCODING utf8, QUOTE \'\`\', HEADER)" \
--host "\$BULK_DB_HOST" \
--username "\$BULK_DB_USER" \
--dbname "\$BULK_DB_NAME"
Expand Down

0 comments on commit b91fbf5

Please sign in to comment.