Skip to content

Commit

Permalink
Merge pull request #4519 from v-anne/4507-pray-and-pay-API
Browse files Browse the repository at this point in the history
4507 pray and pay api
  • Loading branch information
mlissner authored Oct 15, 2024
2 parents ab84c37 + 11971ab commit 710ff4b
Show file tree
Hide file tree
Showing 17 changed files with 690 additions and 29 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,6 @@ IA_ACCESS_KEY=""
IA_SECRET_KEY=""

FTM_KEY=""

# CL API key for cloning data
CL_API_KEY=""
3 changes: 3 additions & 0 deletions cl/api/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@
r"docket-tags", favorite_views.DocketTagViewSet, basename="DocketTag"
)

# Prayers
router.register(r"prayers", favorite_views.PrayerViewSet, basename="prayer")

# Visualizations
router.register(
r"visualizations/json", viz_views.JSONViewSet, basename="jsonversion"
Expand Down
8 changes: 8 additions & 0 deletions cl/assets/static-global/css/override.css
Original file line number Diff line number Diff line change
Expand Up @@ -1723,3 +1723,11 @@ rect.series-segment {
opacity 150ms 150ms ease-in;
transform: translate3d(0, 0, 0);
}

.prayer-button[data-gap-size="small"] {
margin-left: 8px;
}

.prayer-button[data-gap-size="large"]{
margin-left: 44px;
}
13 changes: 9 additions & 4 deletions cl/assets/templates/base.html
Original file line number Diff line number Diff line change
Expand Up @@ -231,17 +231,22 @@ <h1>You did not supply the "private" variable to your template.
<li>
<a href="https://free.law/recap/" tabindex="202">Install RECAP</a>
</li>
{% flag "pray-and-pay" %}
<li>
<a href="{% url "top_prayers" %}#recap-alerts" tabindex="203">Pray and Pay Project</a>
</li>
{% endflag %}
<li>
<a href="{% url "alert_help" %}#recap-alerts" tabindex="203">Get Case Alerts</a>
<a href="{% url "alert_help" %}#recap-alerts" tabindex="204">Get Case Alerts</a>
</li>
<li>
<a href="{% url "coverage_recap" %}" tabindex="204">About this Collection</a>
<a href="{% url "coverage_recap" %}" tabindex="205">About this Collection</a>
</li>
<li>
<a href="https://free.law/data-consulting/" tabindex="205">Bulk Data Service</a>
<a href="https://free.law/data-consulting/" tabindex="206">Bulk Data Service</a>
</li>
<li>
<a href="{% url "pacer_api_help" %}" tabindex="206">API</a>
<a href="{% url "pacer_api_help" %}" tabindex="207">API</a>
</li>
</ul>
</li>
Expand Down
37 changes: 36 additions & 1 deletion cl/favorites/api_serializers.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
from asgiref.sync import async_to_sync
from django.conf import settings
from drf_dynamic_fields import DynamicFieldsMixin
from rest_framework import serializers
from rest_framework.exceptions import ValidationError
from rest_framework.serializers import ModelSerializer

from cl.favorites.models import DocketTag, UserTag
from cl.favorites.models import DocketTag, Prayer, UserTag
from cl.favorites.utils import prayer_eligible
from cl.search.models import Docket


Expand Down Expand Up @@ -37,3 +41,34 @@ class DocketTagSerializer(DynamicFieldsMixin, ModelSerializer):
class Meta:
model = DocketTag
fields = "__all__"


class PrayerSerializer(DynamicFieldsMixin, serializers.ModelSerializer):
user = serializers.HiddenField(default=serializers.CurrentUserDefault())

class Meta:
model = Prayer
fields = "__all__"
read_only_fields = (
"date_created",
"user",
)

def validate(self, data):
user = self.context["request"].user
recap_document = data.get("recap_document")

# Check if a Prayer for the same user and recap_document already exists
if Prayer.objects.filter(
user=user, recap_document=recap_document
).exists():
raise ValidationError(
"A prayer for this recap document already exists."
)

# Check if the user is eligible to create a new prayer
if not async_to_sync(prayer_eligible)(user):
raise ValidationError(
f"You have reached the maximum number of prayers ({settings.ALLOWED_PRAYER_COUNT}) allowed in the last 24 hours."
)
return data
37 changes: 34 additions & 3 deletions cl/favorites/api_views.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@
from rest_framework.viewsets import ModelViewSet

from cl.api.pagination import MediumAdjustablePagination
from cl.api.utils import LoggingMixin
from cl.favorites.api_permissions import IsTagOwner
from cl.favorites.api_serializers import DocketTagSerializer, UserTagSerializer
from cl.favorites.filters import DocketTagFilter, UserTagFilter
from cl.favorites.models import DocketTag, UserTag
from cl.favorites.api_serializers import (
DocketTagSerializer,
PrayerSerializer,
UserTagSerializer,
)
from cl.favorites.filters import DocketTagFilter, PrayerFilter, UserTagFilter
from cl.favorites.models import DocketTag, Prayer, UserTag


class UserTagViewSet(ModelViewSet):
Expand Down Expand Up @@ -51,3 +56,29 @@ def get_queryset(self):
return DocketTag.objects.filter(
Q(tag__user=self.request.user) | Q(tag__published=True)
)


class PrayerViewSet(LoggingMixin, ModelViewSet):
"""A ModelViewset to handle CRUD operations for Prayer."""

permission_classes = [IsAuthenticated]
serializer_class = PrayerSerializer
pagination_class = MediumAdjustablePagination
filterset_class = PrayerFilter
ordering_fields = ("date_created",)
# Default cursor ordering key
ordering = "-date_created"
# Additional cursor ordering fields
cursor_ordering_fields = ["date_created"]
# Only allow these methods. Restricting PUT and PATCH.
http_method_names = ["get", "post", "delete", "head", "options"]

def get_queryset(self):
"""
Return a list of all the open prayers
for the currently authenticated user.
"""
user = self.request.user
return Prayer.objects.filter(
user=user, status=Prayer.WAITING
).order_by("-date_created")
18 changes: 17 additions & 1 deletion cl/favorites/filters.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import rest_framework_filters as filters

from cl.api.utils import BASIC_TEXT_LOOKUPS, BOOLEAN_LOOKUPS, NoEmptyFilterSet
from cl.favorites.models import DocketTag, UserTag
from cl.favorites.models import DocketTag, Prayer, UserTag


class UserTagFilter(NoEmptyFilterSet):
Expand All @@ -21,3 +21,19 @@ class DocketTagFilter(NoEmptyFilterSet):
class Meta:
model = DocketTag
fields = {"id": ["exact"], "docket": ["exact"]}


class PrayerFilter(NoEmptyFilterSet):
date_created = filters.DateFromToRangeFilter(
field_name="date_created",
help_text="Filter prayers by a date range (e.g., ?date_created_after=2024-09-01&date_created_before=2024-12-31).",
)

class Meta:
model = Prayer
fields = {
"date_created": ["exact", "range"],
"user": ["exact"],
"recap_document": ["exact"],
"status": ["exact", "in"],
}
24 changes: 21 additions & 3 deletions cl/favorites/templates/top_prayers.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@
{% load extras %}
{% load text_filters %}
{% load static %}

{% load pacer %}

{% block title %}RECAP Requests – CourtListener.com{% endblock %}
{% block og_title %}RECAP Requests – CourtListener.com{% endblock %}

{% block description %}Lorem Ipsum on CourtListener.{% endblock %}
{% block og_description %}Lorem Ipsum on CourtListener.{% endblock %}
{% block description %}RECAP Requests on CourtListener.{% endblock %}
{% block og_description %}RECAP Requests on CourtListener.{% endblock %}


{% block content %}

<div class="col-xs-12">
<div class="table-responsive">
<table class="settings-table table">
Expand All @@ -21,6 +23,7 @@
<th>Document Number</th>
<th>PACER Doc ID</th>
<th>Document Court</th>
<th>Buy on Pacer</th>
</tr>
</thead>
<tbody>
Expand All @@ -31,6 +34,15 @@
<td>{{ prayer.document_number }}</td>
<td>{{ prayer.pacer_doc_id }}</td>
<td>{{ prayer.docket_entry.docket.court_id }}</td>
<td><a href="{{ prayer.pacer_url }}"
{% if not request.COOKIES.buy_on_pacer_modal and not request.COOKIES.recap_install_plea %}
class="open_buy_pacer_modal btn btn-default btn-xs"
data-toggle="modal" data-target="#modal-buy-pacer"
{% else%}
class="btn btn-default btn-xs"
{% endif %}
target="_blank"
rel="nofollow">Buy on PACER {% if prayer.page_count %}(${{ prayer|price }}){% endif %}</td>
</tr>
{% empty %}
<tr>
Expand All @@ -42,3 +54,9 @@
</div>
</div>
{% endblock %}

{% block footer-scripts %}
<script defer type="text/javascript"
src="{% static "js/buy_pacer_modal.js" %}"></script>
{% include "includes/buy_pacer_modal.html" %}
{% endblock %}
Loading

0 comments on commit 710ff4b

Please sign in to comment.