Compare commits
7 Commits
04ca92b5fe
...
8b1722d1f0
Author | SHA1 | Date | |
---|---|---|---|
8b1722d1f0 | |||
df4c5564c4 | |||
1310e72e3f | |||
281c882a82 | |||
7236b55467 | |||
9c2084903f | |||
25fbe3d352 |
@ -178,6 +178,7 @@ class Base(Configuration):
|
|||||||
class NonCIBase(Base):
|
class NonCIBase(Base):
|
||||||
"""required for all but CI"""
|
"""required for all but CI"""
|
||||||
|
|
||||||
|
CSRF_TRUSTED_ORIGINS = values.ListValue([])
|
||||||
DATABASES = values.DatabaseURLValue(environ_required=True)
|
DATABASES = values.DatabaseURLValue(environ_required=True)
|
||||||
EMAIL = values.EmailURLValue(environ_required=True)
|
EMAIL = values.EmailURLValue(environ_required=True)
|
||||||
# TODO: should validate emails
|
# TODO: should validate emails
|
||||||
|
@ -108,11 +108,6 @@ class EventMeetingTimeInline(admin.TabularInline):
|
|||||||
|
|
||||||
readonly_fields = ["duration"]
|
readonly_fields = ["duration"]
|
||||||
|
|
||||||
# TODO: remove when switched to GeneratedField
|
|
||||||
@admin.display()
|
|
||||||
def duration(self, obj):
|
|
||||||
return obj.duration
|
|
||||||
|
|
||||||
|
|
||||||
@admin.register(EventInstructor)
|
@admin.register(EventInstructor)
|
||||||
class EventInstructorAdmin(admin.ModelAdmin):
|
class EventInstructorAdmin(admin.ModelAdmin):
|
||||||
@ -144,7 +139,7 @@ class EventAdmin(DjangoObjectActions, admin.ModelAdmin):
|
|||||||
show_facets = admin.ShowFacets.ALWAYS
|
show_facets = admin.ShowFacets.ALWAYS
|
||||||
search_fields = ["eid", "title", "url"]
|
search_fields = ["eid", "title", "url"]
|
||||||
date_hierarchy = "start"
|
date_hierarchy = "start"
|
||||||
exclude = ["url", "details"]
|
exclude = ["url", "details", "registrations"]
|
||||||
autocomplete_fields = ["instructor"]
|
autocomplete_fields = ["instructor"]
|
||||||
change_actions = ["fetch_details"]
|
change_actions = ["fetch_details"]
|
||||||
actions = ["fetch_details"]
|
actions = ["fetch_details"]
|
||||||
@ -160,7 +155,7 @@ class EventAdmin(DjangoObjectActions, admin.ModelAdmin):
|
|||||||
else:
|
else:
|
||||||
fields.append(field.name)
|
fields.append(field.name)
|
||||||
fields.insert(fields.index("end") + 1, "duration")
|
fields.insert(fields.index("end") + 1, "duration")
|
||||||
fields.append("_details_timestamp")
|
fields.append("details_timestamp")
|
||||||
return fields
|
return fields
|
||||||
|
|
||||||
@admin.display(ordering="title")
|
@admin.display(ordering="title")
|
||||||
@ -178,10 +173,6 @@ class EventAdmin(DjangoObjectActions, admin.ModelAdmin):
|
|||||||
obj.url,
|
obj.url,
|
||||||
)
|
)
|
||||||
|
|
||||||
@admin.display(description="Last details fetch")
|
|
||||||
def _details_timestamp(self, obj):
|
|
||||||
return naturaltime(obj.details_timestamp)
|
|
||||||
|
|
||||||
@takes_instance_or_queryset
|
@takes_instance_or_queryset
|
||||||
def fetch_details(self, request, queryset):
|
def fetch_details(self, request, queryset):
|
||||||
scrape_event_details(queryset)
|
scrape_event_details(queryset)
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
# Generated by Django 5.0.6 on 2024-05-08 16:44
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
("membershipworks", "0017_eventext_registrations_alter_eventinvoice_pdf"),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name="eventext",
|
||||||
|
name="details_timestamp",
|
||||||
|
field=models.GeneratedField(
|
||||||
|
db_persist=False,
|
||||||
|
expression=models.Func(
|
||||||
|
models.Func(models.F("details___ts"), function="FROM_UNIXTIME"),
|
||||||
|
template="CONVERT_TZ(%(expressions)s, @@session.time_zone, 'UTC')",
|
||||||
|
),
|
||||||
|
output_field=models.DateTimeField(),
|
||||||
|
verbose_name="Last details fetch",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
@ -520,14 +520,6 @@ class EventExtManager(models.Manager):
|
|||||||
ExpressionWrapper(F("duration"), models.IntegerField()) * F("count"),
|
ExpressionWrapper(F("duration"), models.IntegerField()) * F("count"),
|
||||||
models.DurationField(),
|
models.DurationField(),
|
||||||
),
|
),
|
||||||
# TODO: this could be a GeneratedField, but that
|
|
||||||
# currently breaks saving when the primary key is
|
|
||||||
# provided (Django 5.0.1)
|
|
||||||
details_timestamp=Func(
|
|
||||||
Func(F("details___ts"), function="FROM_UNIXTIME"),
|
|
||||||
template="CONVERT_TZ(%(expressions)s, @@session.time_zone, 'UTC')",
|
|
||||||
output_field=models.DateTimeField(),
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@ -550,6 +542,16 @@ class EventExt(Event):
|
|||||||
max_digits=13, decimal_places=4, default=0
|
max_digits=13, decimal_places=4, default=0
|
||||||
)
|
)
|
||||||
details = models.JSONField(null=True, blank=True)
|
details = models.JSONField(null=True, blank=True)
|
||||||
|
details_timestamp = models.GeneratedField(
|
||||||
|
expression=Func(
|
||||||
|
Func(F("details___ts"), function="FROM_UNIXTIME"),
|
||||||
|
template="CONVERT_TZ(%(expressions)s, @@session.time_zone, 'UTC')",
|
||||||
|
),
|
||||||
|
output_field=models.DateTimeField(),
|
||||||
|
db_persist=False,
|
||||||
|
verbose_name="Last details fetch",
|
||||||
|
)
|
||||||
|
|
||||||
registrations = models.JSONField(null=True, blank=True)
|
registrations = models.JSONField(null=True, blank=True)
|
||||||
|
|
||||||
def get_absolute_url(self) -> str:
|
def get_absolute_url(self) -> str:
|
||||||
|
@ -65,6 +65,30 @@ class EventTable(tables.Table):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class EventRegistrationsTable(tables.Table):
|
||||||
|
ticket_count = tables.Column(empty_values=())
|
||||||
|
name = tables.Column(accessor="Full name")
|
||||||
|
email = tables.EmailColumn(accessor="Email")
|
||||||
|
phone = tables.Column(accessor="Phone")
|
||||||
|
emergency_contact_name = tables.Column(accessor="Emergency Contact Name:")
|
||||||
|
emergency_contact_phone_number = tables.Column(
|
||||||
|
accessor="Emergency Contact Phone Number:"
|
||||||
|
)
|
||||||
|
emergency_contact_relation = tables.Column(accessor="Emergency Contact Relation:")
|
||||||
|
|
||||||
|
def render_ticket_count(self, record):
|
||||||
|
return sum(int(v) for k, v in record.items() if k.startswith("Ticket: "))
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
row_attrs = {
|
||||||
|
"class": lambda table, record: (
|
||||||
|
""
|
||||||
|
if table.render_ticket_count(record) > 0
|
||||||
|
else "text-decoration-line-through table-danger"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class EventSummaryTable(tables.Table):
|
class EventSummaryTable(tables.Table):
|
||||||
event_count = tables.Column("Events")
|
event_count = tables.Column("Events")
|
||||||
canceled_event_count = tables.Column("Canceled Events")
|
canceled_event_count = tables.Column("Canceled Events")
|
||||||
|
@ -0,0 +1,15 @@
|
|||||||
|
{% if perms.membershipworks.view_eventext %}
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="{% url 'membershipworks:event-index-report' %}">MW Event Reports</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="{% url 'membershipworks:event-year-report' event.start|date:"Y" %}">{{ event.start|date:"Y" }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="{% url 'membershipworks:event-month-report' event.start|date:"Y" event.start|date:"m" %}">{{ event.start|date:"F" }}</a>
|
||||||
|
</li>
|
||||||
|
{% else %}
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="{% url 'membershipworks:user-events' %}">My Events</a>
|
||||||
|
</li>
|
||||||
|
{% endif %}
|
@ -7,8 +7,16 @@
|
|||||||
{% block admin_link %}
|
{% block admin_link %}
|
||||||
{% url 'admin:membershipworks_eventext_change' event.pk %}
|
{% url 'admin:membershipworks_eventext_change' event.pk %}
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
{% block breadcrumbs %}
|
||||||
|
{% include "./components/event_breadcrumbs.dj.html" %}
|
||||||
|
<li class="breadcrumb-item active" aria-current="page">{{ event.details.ttl|nh3 }}</li>
|
||||||
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
{% if event.registrations is not None %}
|
||||||
|
{% url 'membershipworks:event-registrations' event.pk as registrations_url %}
|
||||||
|
{% bootstrap_button href=registrations_url content="Show Registrations" %}
|
||||||
|
{% endif %}
|
||||||
{% include "membershipworks/event_invoice.dj.html" %}
|
{% include "membershipworks/event_invoice.dj.html" %}
|
||||||
|
|
||||||
<div class="card w-auto mt-5">
|
<div class="card w-auto mt-5">
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
{% extends "base.dj.html" %}
|
||||||
|
|
||||||
|
{% load nh3_tags %}
|
||||||
|
{% load render_table from django_tables2 %}
|
||||||
|
{% load django_bootstrap5 %}
|
||||||
|
|
||||||
|
{% block title %}Registrations for {{ event.details.ttl|nh3 }}{% endblock %}
|
||||||
|
{% block admin_link %}
|
||||||
|
{% url 'admin:membershipworks_eventext_change' event.pk %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block breadcrumbs %}
|
||||||
|
{% include "./components/event_breadcrumbs.dj.html" %}
|
||||||
|
<li class="breadcrumb-item">
|
||||||
|
<a href="{% url 'membershipworks:event-detail' event.pk %}">{{ event.details.ttl|nh3|truncatechars_html:40 }}</a>
|
||||||
|
</li>
|
||||||
|
<li class="breadcrumb-item active" aria-current="page">Registrations</li>
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<div class="container">
|
||||||
|
<div class="row justify-content-center">
|
||||||
|
<div class="col-auto">
|
||||||
|
{% bootstrap_button extra_classes="btn-sm" href=email_link target="_blank" content="Email all attendees" %}
|
||||||
|
</div>
|
||||||
|
<div class="col-auto">{% include "cmsmanage/components/download_table.dj.html" %}</div>
|
||||||
|
</div>
|
||||||
|
{% render_table table %}
|
||||||
|
<p class="text-center">Data last updated {{ event.details_timestamp }}</p>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
@ -3,6 +3,7 @@
|
|||||||
{% load render_table from django_tables2 %}
|
{% load render_table from django_tables2 %}
|
||||||
|
|
||||||
{% block title %}My Events{% endblock %}
|
{% block title %}My Events{% endblock %}
|
||||||
|
{% block breadcrumbs %}<li class="breadcrumb-item active" aria-current="page">My Events</li>{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% include "cmsmanage/components/download_table.dj.html" %}
|
{% include "cmsmanage/components/download_table.dj.html" %}
|
||||||
|
|
||||||
|
@ -45,6 +45,11 @@ urlpatterns = [
|
|||||||
views.EventDetailView.as_view(),
|
views.EventDetailView.as_view(),
|
||||||
name="event-detail",
|
name="event-detail",
|
||||||
),
|
),
|
||||||
|
path(
|
||||||
|
"event/<eid>/registrations",
|
||||||
|
views.EventRegistrationsView.as_view(),
|
||||||
|
name="event-registrations",
|
||||||
|
),
|
||||||
path(
|
path(
|
||||||
"event/invoice/<uuid:uuid>.pdf",
|
"event/invoice/<uuid:uuid>.pdf",
|
||||||
views.EventInvoicePDFView.as_view(),
|
views.EventInvoicePDFView.as_view(),
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import uuid
|
import uuid
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
from urllib.parse import quote, urlencode
|
||||||
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
@ -46,6 +47,7 @@ from .invoice_email import make_invoice_emails
|
|||||||
from .models import EventAttendee, EventExt, EventInvoice, Member
|
from .models import EventAttendee, EventExt, EventInvoice, Member
|
||||||
from .tables import (
|
from .tables import (
|
||||||
EventAttendeeTable,
|
EventAttendeeTable,
|
||||||
|
EventRegistrationsTable,
|
||||||
EventSummaryTable,
|
EventSummaryTable,
|
||||||
EventTable,
|
EventTable,
|
||||||
InvoiceTable,
|
InvoiceTable,
|
||||||
@ -418,6 +420,50 @@ class EventInvoicePDFView(AccessMixin, BaseDetailView):
|
|||||||
return self.handle_no_permission()
|
return self.handle_no_permission()
|
||||||
|
|
||||||
|
|
||||||
|
class EventRegistrationsView(ExportMixin, SingleTableMixin, AccessMixin, DetailView):
|
||||||
|
permission_required = "membershipworks.view_eventext"
|
||||||
|
model = EventExt
|
||||||
|
pk_url_kwarg = "eid"
|
||||||
|
context_object_name = "event"
|
||||||
|
template_name = "membershipworks/event_registrations.dj.html"
|
||||||
|
table_class = EventRegistrationsTable
|
||||||
|
export_formats = ("csv", "xlsx", "ods")
|
||||||
|
|
||||||
|
def render_to_response(
|
||||||
|
self, context: dict[str, Any], **response_kwargs: Any
|
||||||
|
) -> HttpResponse:
|
||||||
|
if self.request.user.has_perm(
|
||||||
|
self.permission_required
|
||||||
|
) or self.object.user_is_instructor(self.request.user):
|
||||||
|
return super().render_to_response(context, **response_kwargs)
|
||||||
|
else:
|
||||||
|
return self.handle_no_permission()
|
||||||
|
|
||||||
|
def get_context_data(self, **kwargs: Any) -> dict[str, Any]:
|
||||||
|
context_data = super().get_context_data(**kwargs)
|
||||||
|
|
||||||
|
context_data["email_link"] = "mailto:?" + urlencode(
|
||||||
|
{
|
||||||
|
"subject": f"[CMS Event] {self.object.title}",
|
||||||
|
"bcc": ",".join(
|
||||||
|
mail.message.sanitize_address(
|
||||||
|
(reg["Full name"], reg["Email"]), settings.DEFAULT_CHARSET
|
||||||
|
)
|
||||||
|
for reg in self.object.registrations
|
||||||
|
if any(
|
||||||
|
int(v) > 0 for k, v in reg.items() if k.startswith("Ticket: ")
|
||||||
|
)
|
||||||
|
),
|
||||||
|
},
|
||||||
|
quote_via=quote,
|
||||||
|
)
|
||||||
|
|
||||||
|
return context_data
|
||||||
|
|
||||||
|
def get_table_data(self):
|
||||||
|
return self.object.registrations
|
||||||
|
|
||||||
|
|
||||||
class EventAttendeeFilters(django_filters.FilterSet):
|
class EventAttendeeFilters(django_filters.FilterSet):
|
||||||
new_since = django_filters.DateFilter(
|
new_since = django_filters.DateFilter(
|
||||||
field_name="event__start", method="filter_new_since"
|
field_name="event__start", method="filter_new_since"
|
||||||
|
76
pdm.lock
generated
76
pdm.lock
generated
@ -5,7 +5,7 @@
|
|||||||
groups = ["default", "debug", "lint", "server", "typing", "dev"]
|
groups = ["default", "debug", "lint", "server", "typing", "dev"]
|
||||||
strategy = ["cross_platform"]
|
strategy = ["cross_platform"]
|
||||||
lock_version = "4.4.1"
|
lock_version = "4.4.1"
|
||||||
content_hash = "sha256:8e68a7f1608469e70bc3e7502f747bbe5f38ca4bc15f504811377509599bb7a1"
|
content_hash = "sha256:651200bd58f4159fe99a599564e0f83a89fd149e5e7300abd151d6a3bb6477a9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "aiohttp"
|
name = "aiohttp"
|
||||||
@ -483,7 +483,7 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "django"
|
name = "django"
|
||||||
version = "5.0.4"
|
version = "5.0.6"
|
||||||
requires_python = ">=3.10"
|
requires_python = ">=3.10"
|
||||||
summary = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
|
summary = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
|
||||||
dependencies = [
|
dependencies = [
|
||||||
@ -492,8 +492,8 @@ dependencies = [
|
|||||||
"tzdata; sys_platform == \"win32\"",
|
"tzdata; sys_platform == \"win32\"",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "Django-5.0.4-py3-none-any.whl", hash = "sha256:916423499d75d62da7aa038d19aef23d23498d8df229775eb0a6309ee1013775"},
|
{file = "Django-5.0.6-py3-none-any.whl", hash = "sha256:8363ac062bb4ef7c3f12d078f6fa5d154031d129a15170a1066412af49d30905"},
|
||||||
{file = "Django-5.0.4.tar.gz", hash = "sha256:4bd01a8c830bb77a8a3b0e7d8b25b887e536ad17a81ba2dce5476135c73312bd"},
|
{file = "Django-5.0.6.tar.gz", hash = "sha256:ff1b61005004e476e0aeea47c7f79b85864c70124030e95146315396f1e7951f"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -578,15 +578,15 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "django-db-views"
|
name = "django-db-views"
|
||||||
version = "0.1.6"
|
version = "0.1.7"
|
||||||
summary = "Handle database views. Allow to create migrations for database views. View migrations using django code. They can be reversed. Changes in model view definition are detected automatically. Support almost all options as regular makemigrations command"
|
summary = "Handle database views. Allow to create migrations for database views. View migrations using django code. They can be reversed. Changes in model view definition are detected automatically. Support almost all options as regular makemigrations command"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"Django",
|
"Django",
|
||||||
"six",
|
"six",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "django-db-views-0.1.6.tar.gz", hash = "sha256:05718bb87c819323d577b294ee75f25807e5bb767793aa27f1ecc4c7ae073172"},
|
{file = "django-db-views-0.1.7.tar.gz", hash = "sha256:7c0dc78aa5f53cc4eefc4d880450a8cb61bb8376b5494356e20383f71a3e1657"},
|
||||||
{file = "django_db_views-0.1.6-py3-none-any.whl", hash = "sha256:1ae8a6b389a2e8a7a2e246050ce7688780343bf4fd4f9622263b607ae27e5524"},
|
{file = "django_db_views-0.1.7-py3-none-any.whl", hash = "sha256:ffa399af1678e60f532f8c2b531927e94e8249e1012a83fc865234384419bff8"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1079,7 +1079,7 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hypothesis"
|
name = "hypothesis"
|
||||||
version = "6.100.2"
|
version = "6.100.5"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "A library for property-based testing"
|
summary = "A library for property-based testing"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
@ -1087,23 +1087,23 @@ dependencies = [
|
|||||||
"sortedcontainers<3.0.0,>=2.1.0",
|
"sortedcontainers<3.0.0,>=2.1.0",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "hypothesis-6.100.2-py3-none-any.whl", hash = "sha256:4ae5918f5a47f979e53fe9e8be4ba6edf17d7a133c13542938d8a6e18f890a2a"},
|
{file = "hypothesis-6.100.5-py3-none-any.whl", hash = "sha256:d2f875a8791abdf68599e85cc9238f7239a73b72362d34be95e532e811766723"},
|
||||||
{file = "hypothesis-6.100.2.tar.gz", hash = "sha256:7d68e45d371cee5b9d2236516341aca57fb7f2cfabef6cb9e5b3a7ec62219cf2"},
|
{file = "hypothesis-6.100.5.tar.gz", hash = "sha256:14e06081459ee96ca8f1ed996b6fc19f71910281e01f6a9fa3d9d6e68bbe4a25"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "hypothesis"
|
name = "hypothesis"
|
||||||
version = "6.100.2"
|
version = "6.100.5"
|
||||||
extras = ["django"]
|
extras = ["django"]
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "A library for property-based testing"
|
summary = "A library for property-based testing"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"django>=3.2",
|
"django>=3.2",
|
||||||
"hypothesis==6.100.2",
|
"hypothesis==6.100.5",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "hypothesis-6.100.2-py3-none-any.whl", hash = "sha256:4ae5918f5a47f979e53fe9e8be4ba6edf17d7a133c13542938d8a6e18f890a2a"},
|
{file = "hypothesis-6.100.5-py3-none-any.whl", hash = "sha256:d2f875a8791abdf68599e85cc9238f7239a73b72362d34be95e532e811766723"},
|
||||||
{file = "hypothesis-6.100.2.tar.gz", hash = "sha256:7d68e45d371cee5b9d2236516341aca57fb7f2cfabef6cb9e5b3a7ec62219cf2"},
|
{file = "hypothesis-6.100.5.tar.gz", hash = "sha256:14e06081459ee96ca8f1ed996b6fc19f71910281e01f6a9fa3d9d6e68bbe4a25"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -1833,27 +1833,27 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ruff"
|
name = "ruff"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
requires_python = ">=3.7"
|
requires_python = ">=3.7"
|
||||||
summary = "An extremely fast Python linter and code formatter, written in Rust."
|
summary = "An extremely fast Python linter and code formatter, written in Rust."
|
||||||
files = [
|
files = [
|
||||||
{file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d14dc8953f8af7e003a485ef560bbefa5f8cc1ad994eebb5b12136049bbccc5"},
|
{file = "ruff-0.4.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b70800c290f14ae6fcbb41bbe201cf62dfca024d124a1f373e76371a007454ce"},
|
||||||
{file = "ruff-0.4.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:24016ed18db3dc9786af103ff49c03bdf408ea253f3cb9e3638f39ac9cf2d483"},
|
{file = "ruff-0.4.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:08a0d6a22918ab2552ace96adeaca308833873a4d7d1d587bb1d37bae8728eb3"},
|
||||||
{file = "ruff-0.4.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e2e06459042ac841ed510196c350ba35a9b24a643e23db60d79b2db92af0c2b"},
|
{file = "ruff-0.4.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eba1f14df3c758dd7de5b55fbae7e1c8af238597961e5fb628f3de446c3c40c5"},
|
||||||
{file = "ruff-0.4.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3afabaf7ba8e9c485a14ad8f4122feff6b2b93cc53cd4dad2fd24ae35112d5c5"},
|
{file = "ruff-0.4.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:819fb06d535cc76dfddbfe8d3068ff602ddeb40e3eacbc90e0d1272bb8d97113"},
|
||||||
{file = "ruff-0.4.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:799eb468ea6bc54b95527143a4ceaf970d5aa3613050c6cff54c85fda3fde480"},
|
{file = "ruff-0.4.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0bfc9e955e6dc6359eb6f82ea150c4f4e82b660e5b58d9a20a0e42ec3bb6342b"},
|
||||||
{file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:ec4ba9436a51527fb6931a8839af4c36a5481f8c19e8f5e42c2f7ad3a49f5069"},
|
{file = "ruff-0.4.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:510a67d232d2ebe983fddea324dbf9d69b71c4d2dfeb8a862f4a127536dd4cfb"},
|
||||||
{file = "ruff-0.4.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6a2243f8f434e487c2a010c7252150b1fdf019035130f41b77626f5655c9ca22"},
|
{file = "ruff-0.4.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dc9ff11cd9a092ee7680a56d21f302bdda14327772cd870d806610a3503d001f"},
|
||||||
{file = "ruff-0.4.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8772130a063f3eebdf7095da00c0b9898bd1774c43b336272c3e98667d4fb8fa"},
|
{file = "ruff-0.4.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:29efff25bf9ee685c2c8390563a5b5c006a3fee5230d28ea39f4f75f9d0b6f2f"},
|
||||||
{file = "ruff-0.4.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ab165ef5d72392b4ebb85a8b0fbd321f69832a632e07a74794c0e598e7a8376"},
|
{file = "ruff-0.4.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18b00e0bcccf0fc8d7186ed21e311dffd19761cb632241a6e4fe4477cc80ef6e"},
|
||||||
{file = "ruff-0.4.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:1f32cadf44c2020e75e0c56c3408ed1d32c024766bd41aedef92aa3ca28eef68"},
|
{file = "ruff-0.4.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262f5635e2c74d80b7507fbc2fac28fe0d4fef26373bbc62039526f7722bca1b"},
|
||||||
{file = "ruff-0.4.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:22e306bf15e09af45ca812bc42fa59b628646fa7c26072555f278994890bc7ac"},
|
{file = "ruff-0.4.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7363691198719c26459e08cc17c6a3dac6f592e9ea3d2fa772f4e561b5fe82a3"},
|
||||||
{file = "ruff-0.4.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:82986bb77ad83a1719c90b9528a9dd663c9206f7c0ab69282af8223566a0c34e"},
|
{file = "ruff-0.4.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:eeb039f8428fcb6725bb63cbae92ad67b0559e68b5d80f840f11914afd8ddf7f"},
|
||||||
{file = "ruff-0.4.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:652e4ba553e421a6dc2a6d4868bc3b3881311702633eb3672f9f244ded8908cd"},
|
{file = "ruff-0.4.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:927b11c1e4d0727ce1a729eace61cee88a334623ec424c0b1c8fe3e5f9d3c865"},
|
||||||
{file = "ruff-0.4.2-py3-none-win32.whl", hash = "sha256:7891ee376770ac094da3ad40c116258a381b86c7352552788377c6eb16d784fe"},
|
{file = "ruff-0.4.3-py3-none-win32.whl", hash = "sha256:25cacda2155778beb0d064e0ec5a3944dcca9c12715f7c4634fd9d93ac33fd30"},
|
||||||
{file = "ruff-0.4.2-py3-none-win_amd64.whl", hash = "sha256:5ec481661fb2fd88a5d6cf1f83403d388ec90f9daaa36e40e2c003de66751798"},
|
{file = "ruff-0.4.3-py3-none-win_amd64.whl", hash = "sha256:7a1c3a450bc6539ef00da6c819fb1b76b6b065dec585f91456e7c0d6a0bbc725"},
|
||||||
{file = "ruff-0.4.2-py3-none-win_arm64.whl", hash = "sha256:cbd1e87c71bca14792948c4ccb51ee61c3296e164019d2d484f3eaa2d360dfaf"},
|
{file = "ruff-0.4.3-py3-none-win_arm64.whl", hash = "sha256:71ca5f8ccf1121b95a59649482470c5601c60a416bf189d553955b0338e34614"},
|
||||||
{file = "ruff-0.4.2.tar.gz", hash = "sha256:33bcc160aee2520664bc0859cfeaebc84bb7323becff3f303b8f1f2d81cb4edc"},
|
{file = "ruff-0.4.3.tar.gz", hash = "sha256:ff0a3ef2e3c4b6d133fbedcf9586abfbe38d076041f2dc18ffb2c7e0485d5a07"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2094,7 +2094,7 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "types-pygments"
|
name = "types-pygments"
|
||||||
version = "2.17.0.20240310"
|
version = "2.18.0.20240506"
|
||||||
requires_python = ">=3.8"
|
requires_python = ">=3.8"
|
||||||
summary = "Typing stubs for Pygments"
|
summary = "Typing stubs for Pygments"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
@ -2102,8 +2102,8 @@ dependencies = [
|
|||||||
"types-setuptools",
|
"types-setuptools",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "types-Pygments-2.17.0.20240310.tar.gz", hash = "sha256:b1d97e905ce36343c7283b0319182ae6d4f967188f361f45502a18ae43e03e1f"},
|
{file = "types-Pygments-2.18.0.20240506.tar.gz", hash = "sha256:4b4c37812c87bbde687dbf27adf5bac593745a321e57f678dbc311571ba2ac9d"},
|
||||||
{file = "types_Pygments-2.17.0.20240310-py3-none-any.whl", hash = "sha256:b101ca9448aaff52af6966506f1fdd73b1e60a79b8a79a8bace3366cbf1f7ed9"},
|
{file = "types_Pygments-2.18.0.20240506-py3-none-any.whl", hash = "sha256:11c90bc1737c9af55e5569558b88df7c2233e12325cb516215f722271444e91d"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -2311,7 +2311,7 @@ files = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "weasyprint"
|
name = "weasyprint"
|
||||||
version = "62.0"
|
version = "62.1"
|
||||||
requires_python = ">=3.9"
|
requires_python = ">=3.9"
|
||||||
summary = "The Awesome Document Factory"
|
summary = "The Awesome Document Factory"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
@ -2325,8 +2325,8 @@ dependencies = [
|
|||||||
"tinycss2>=1.3.0",
|
"tinycss2>=1.3.0",
|
||||||
]
|
]
|
||||||
files = [
|
files = [
|
||||||
{file = "weasyprint-62.0-py3-none-any.whl", hash = "sha256:021b2fcde720756dd496645f251e40240b742e91a85f446f612f4666fdca316d"},
|
{file = "weasyprint-62.1-py3-none-any.whl", hash = "sha256:654d4c266336cbf9acc4da118c7778ef5839717e6055d5b8f995cf50be200c46"},
|
||||||
{file = "weasyprint-62.0.tar.gz", hash = "sha256:9f56eaefdaafcf35ae568c56eee5dba189af1272a46f4d205bd12936315f9481"},
|
{file = "weasyprint-62.1.tar.gz", hash = "sha256:bf3c1a9ac4194271a7cf117229c093744105b50ac2fa64c0a6e44e68ae742992"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -18,7 +18,7 @@ dependencies = [
|
|||||||
"mdformat-tables~=0.4",
|
"mdformat-tables~=0.4",
|
||||||
"mysqlclient~=2.2",
|
"mysqlclient~=2.2",
|
||||||
"django-autocomplete-light~=3.11",
|
"django-autocomplete-light~=3.11",
|
||||||
"weasyprint~=62.0",
|
"weasyprint~=62.1",
|
||||||
"requests~=2.31",
|
"requests~=2.31",
|
||||||
"semver~=3.0",
|
"semver~=3.0",
|
||||||
"djangorestframework~=3.15",
|
"djangorestframework~=3.15",
|
||||||
@ -124,7 +124,7 @@ typing = [
|
|||||||
"types-urllib3~=1.26",
|
"types-urllib3~=1.26",
|
||||||
"djangorestframework-stubs[compatible-mypy]~=3.15",
|
"djangorestframework-stubs[compatible-mypy]~=3.15",
|
||||||
"types-Markdown~=3.6",
|
"types-Markdown~=3.6",
|
||||||
"types-Pygments~=2.17",
|
"types-Pygments~=2.18",
|
||||||
"types-psycopg2~=2.9",
|
"types-psycopg2~=2.9",
|
||||||
"types-lxml~=2024.4",
|
"types-lxml~=2024.4",
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user