Skip to content

Commit

Permalink
Merge branch 'main' into 5116-make-citation-use-corrected-page
Browse files Browse the repository at this point in the history
  • Loading branch information
grossir authored Feb 28, 2025
2 parents e894413 + 00c8929 commit f142eac
Show file tree
Hide file tree
Showing 13 changed files with 796 additions and 24 deletions.
1 change: 0 additions & 1 deletion cl/api/templates/rest-docs-v2.html
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
{% extends "base.html" %}
{% load static %}


{% block title %}REST API, v2 – CourtListener.com{% endblock %}
{% block description %}
The first REST API for federal and state case law and still the best.
Expand Down
2 changes: 0 additions & 2 deletions cl/api/templates/rest-docs-vlatest.html
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ <h1 id="about">REST API &ndash; v4.1</h1>

<p class="lead">APIs for developers and researchers that need granular legal data.
</p>
<p class="alert alert-warning">A new version of the API is now live! Please read <a href="{% url "migration_guide" %}">our migration guide</a> to update. The <a href="{% url "rest_docs" version="v3" %}">old version of the documentation</a> is maintained for migration purposes only.
</p>
<p>After more than a decade of development, these APIs are powerful. Our <a href="{% url "case_law_api_help" %}">case law API</a> was the first. Our <a href="{% url "pacer_api_help" %}">PACER</a> and <a href="{% url "oral_argument_api_help" %}">oral argument</a> APIs are the biggest. Our <a href="{% url "webhooks_getting_started" %}">webhooks</a> push data to you. Our <a href="{% url "citation_lookup_api" %}">citation lookup tool</a> can fight hallucinations in AI tools.
</p>
<p>Let's get started. To see and browse all the API URLs, click the button below:
Expand Down
8 changes: 6 additions & 2 deletions cl/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,13 @@ async def court_index(request: HttpRequest) -> HttpResponse:


async def rest_docs(request, version=None):
"""Show the correct version of the rest docs"""
"""Show the correct version of the rest docs.
Latest version is shown when not specified in args.
"""
court_count = await Court.objects.acount()
context = {"court_count": court_count, "private": False}
latest = version is None
context = {"court_count": court_count, "private": not latest}
return TemplateResponse(
request,
[f"rest-docs-{version}.html", "rest-docs-vlatest.html"],
Expand Down
18 changes: 15 additions & 3 deletions cl/citations/match_citations.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,29 @@ def resolve_fullcase_citation(

if len(db_search_results) == 0:
# If no citation is found use get_clusters_from_citation as a backup
volume = full_citation.groups.get("volume", None)
reporter = full_citation.groups.get("reporter", None)
page = full_citation.groups.get("page", None)
volume = full_citation.groups.get("volume")
reporter = full_citation.corrected_reporter()
page = full_citation.corrected_page()
if (
volume is not None
and volume.isdigit()
and reporter is not None
and page is not None
):
clusters, _count = async_to_sync(
get_clusters_from_citation_str
)(volume=volume, reporter=reporter, page=page)

# exclude self links
if getattr(full_citation, "citing_opinion", False):
clusters = [
cluster
for cluster in clusters
if cluster.id
!= full_citation.citing_opinion.cluster.pk
]
_count = len(clusters)

if _count == 1:
# return the first item by ordering key
return clusters[0].ordered_opinions.first()
Expand Down
7 changes: 4 additions & 3 deletions cl/citations/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,10 @@ def store_unmatched_citations(
# values in required fields
groups = unmatched_citation.groups
if (
not groups.get("reporter")
or not groups.get("volume")
or not groups.get("page")
not groups.get("reporter", None)
or not groups.get("volume", None)
or not groups.get("volume").isdigit()
or not groups.get("page", None)
):
logger.error(
"Unexpected null value in FullCaseCitation %s",
Expand Down
33 changes: 33 additions & 0 deletions cl/citations/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -768,6 +768,21 @@ def setUpTestData(cls) -> None:
),
)

cls.citation12 = CitationWithParentsFactory.create(
volume="8",
reporter="Barb.",
page="415",
cluster=OpinionClusterFactoryWithChildrenAndParents(
case_name="Shaffer v. Lee",
date_filed=date(1850, 4, 9),
sub_opinions=RelatedFactory(
OpinionWithChildrenFactory,
factory_related_name="cluster",
xml_harvard="""Lorem ipsum,*415 114 F.3d 1182, consectetur *416 adipiscing elit, 114 F.3d 1181""",
),
),
)

call_command(
"cl_index_parent_and_child_docs",
search_type=SEARCH_TYPES.OPINION,
Expand Down Expand Up @@ -1086,6 +1101,24 @@ def test_citation_matching_issue621(self) -> None:
results = resolve_fullcase_citation(citation)
self.assertEqual(NO_MATCH_RESOURCE, results)

def test_citation_resolve_with_corrected_reporter(self) -> None:
"""Resolve to corrected reporter"""
cite_str = "8 B. 415"
citation = get_citations(cite_str, tokenizer=HYPERSCAN_TOKENIZER)[0]
citation.citing_opinion = Opinion.objects.all()[0]
results = resolve_fullcase_citation(citation)
opinion12 = Opinion.objects.get(cluster__pk=self.citation12.cluster_id)
self.assertEqual(results.pk, opinion12.pk, msg=results)

def test_citation_resolve_to_pincite(self) -> None:
"""Resolve to corrected reporter and pin cite inside xml harvard?"""
cite_str = "8 B. 416"
citation = get_citations(cite_str, tokenizer=HYPERSCAN_TOKENIZER)[0]
citation.citing_opinion = Opinion.objects.all()[0]
results = resolve_fullcase_citation(citation)
opinion12 = Opinion.objects.get(cluster__pk=self.citation12.cluster_id)
self.assertEqual(results.pk, opinion12.pk, msg=results)

def test_citation_multiple_matches(self) -> None:
"""Make sure that we can identify multiple matches for a single citation"""
citation_str = "114 F.3d 1182"
Expand Down
2 changes: 1 addition & 1 deletion cl/opinion_page/templates/docket_tabs.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@
</p>
{% endif %}
<h1 class="bottom inline" data-type="search.Docket" data-id="{{ docket.pk }}">
{{ docket|best_case_name|safe|v_wrapper }}
<span class="select-all">{{ docket|best_case_name|safe|v_wrapper }}</span>
{% if docket.docket_number %}
(<span class="select-all">{{ docket.docket_number }}</span>)
{% endif %}
Expand Down
2 changes: 1 addition & 1 deletion cl/opinion_page/templates/opinion.html
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,7 @@ <h3>
{% block content %}
<article class="col-sm-9">
{% with opinion_count=cluster.sub_opinions.all.count %}
<h2 class="inline">{{ caption|safe|v_wrapper }}</h2>
<h2 class="inline select-all">{{ caption|safe|v_wrapper }}</h2>
{% include "includes/notes_modal.html" %}

<h3>{{ cluster.docket.court }}</h3>
Expand Down
16 changes: 8 additions & 8 deletions cl/opinion_page/templates/opinions.html
Original file line number Diff line number Diff line change
Expand Up @@ -227,15 +227,15 @@ <h3>
</div>
</div>

<h1 class="case-caption jump-link" id="caption">{{ cluster|best_case_name|safe }}</h1>
<h1 class="case-caption jump-link select-all" id="caption">{{ cluster|best_case_name|safe }}</h1>
<h4 class="case-court">{{ cluster.docket.court }}</h4>
<br>
<div class="case-details">
<ul class="list-unstyled">
<li><strong>Citations:</strong> {{ cluster.citation_string|default:"None known" }}</li>
<li><strong>Citations:</strong> <span class="select-all">{{ cluster.citation_string|default:"None known" }}</span></li>
{% if cluster.case_name_full != cluster|best_case_name %}
<li><strong>Full Case Name:</strong>
{{ cluster.case_name_full }}
<span class="select-all">{{ cluster.case_name_full }}</span>
</li>
{% endif %}

Expand Down Expand Up @@ -299,28 +299,28 @@ <h4 class="case-court">{{ cluster.docket.court }}</h4>
</div>
</div>

<ul class="nav nav-tabs hidden-print">
<ul class="nav nav-tabs hidden-print nav-justified">
<li role="presentation" {% if tab == "opinions" or tab == "" %} class="active" {% endif %}>
<a href="{% url 'view_case' cluster.pk cluster.slug %}">Opinion</a>
</li>
{% if authorities_count > 0 %}
<li role="presentation" {% if tab == "authorities" %} class="active" {% endif %}>
<a href="{% url "view_case_authorities" cluster.pk cluster.slug %}">Auth<span class="hidden-xs hidden-sm hidden-md">orities&nbsp;({{ authorities_count }})</span></a>
<a href="{% url "view_case_authorities" cluster.pk cluster.slug %}">Authorities&nbsp;({{ authorities_count }})</a>
</li>
{% endif %}
{% if cited_by_count > 0 %}
<li role="presentation" {% if tab == "cited-by" %} class="active" {% endif %}>
<a href="{% url "view_case_cited_by" cluster.pk cluster.slug %}">Cited<span class="hidden-xs hidden-sm hidden-md">&nbsp;By&nbsp;({{ cited_by_count }})</span></a>
<a href="{% url "view_case_cited_by" cluster.pk cluster.slug %}">Cited&nbsp;By&nbsp;({{ cited_by_count }})</a>
</li>
{% endif %}
{% if summaries_count > 0 %}
<li role="presentation" {% if tab == "summaries" %} class="active" {% endif %}>
<a href="{% url "view_case_summaries" cluster.pk cluster.slug %}">Sum<span class="hidden-xs hidden-sm hidden-md">maries&nbsp;({{ summaries_count }})</span></a>
<a href="{% url "view_case_summaries" cluster.pk cluster.slug %}">Summaries&nbsp;({{ summaries_count }})</a>
</li>
{% endif %}
{% if related_cases_count > 0 %}
<li role="presentation" {% if tab == "related-cases" %} class="active" {% endif %}>
<a href="{% url 'view_case_related_cases' cluster.pk cluster.slug %}">Related&nbsp;<span class="hidden-xs hidden-sm hidden-md">Cases</span></a>
<a href="{% url 'view_case_related_cases' cluster.pk cluster.slug %}">Related&nbsp;Cases</a>
</li>
{% endif %}
{% if has_downloads and "pdf" in pdf_path or cluster.filepath_pdf_harvard %}
Expand Down
Loading

0 comments on commit f142eac

Please sign in to comment.