diff --git a/akarpov/blog/forms.py b/akarpov/blog/forms.py index 400c2dd..cbe90c0 100644 --- a/akarpov/blog/forms.py +++ b/akarpov/blog/forms.py @@ -1,11 +1,12 @@ -from ckeditor.fields import RichTextFormField from django import forms +from django_ckeditor_5.fields import CKEditor5Field +from django_ckeditor_5.widgets import CKEditor5Widget from akarpov.blog.models import Post, Tag class PostForm(forms.ModelForm): - body = RichTextFormField(label="") + body = CKEditor5Field(config_name="extends") image = forms.ImageField(help_text="better use horizontal images", required=False) tags = forms.ModelMultipleChoiceField( queryset=Tag.objects.all(), widget=forms.CheckboxSelectMultiple, required=True @@ -14,3 +15,9 @@ class PostForm(forms.ModelForm): class Meta: model = Post fields = ["title", "body", "image", "tags"] + widgets = { + "body": CKEditor5Widget( + attrs={"class": "django_ckeditor_5"}, + config_name="extends", + ) + } diff --git a/akarpov/blog/migrations/0001_initial.py b/akarpov/blog/migrations/0001_initial.py index c215ae4..f4c7b59 100644 --- a/akarpov/blog/migrations/0001_initial.py +++ b/akarpov/blog/migrations/0001_initial.py @@ -1,6 +1,5 @@ # Generated by Django 4.0.8 on 2022-11-23 08:30 -import ckeditor_uploader.fields import colorfield.fields from django.conf import settings from django.db import migrations, models @@ -56,7 +55,7 @@ class Migration(migrations.Migration): ), ), ("title", models.CharField(max_length=100)), - ("body", ckeditor_uploader.fields.RichTextUploadingField()), + ("body", models.TextField()), ("slug", models.SlugField(blank=True, max_length=20)), ("post_views", models.IntegerField(default=0)), ("rating", models.IntegerField(default=0)), diff --git a/akarpov/blog/migrations/0011_alter_post_body.py b/akarpov/blog/migrations/0011_alter_post_body.py new file mode 100644 index 0000000..03c00b7 --- /dev/null +++ b/akarpov/blog/migrations/0011_alter_post_body.py @@ -0,0 +1,18 @@ +# Generated by Django 4.2.10 on 2024-03-29 15:35 + +from django.db import migrations +import django_ckeditor_5.fields + + +class Migration(migrations.Migration): + dependencies = [ + ("blog", "0010_alter_tag_color"), + ] + + operations = [ + migrations.AlterField( + model_name="post", + name="body", + field=django_ckeditor_5.fields.CKEditor5Field(), + ), + ] diff --git a/akarpov/blog/models.py b/akarpov/blog/models.py index fadc746..e3c3665 100644 --- a/akarpov/blog/models.py +++ b/akarpov/blog/models.py @@ -1,8 +1,8 @@ -from ckeditor_uploader.fields import RichTextUploadingField from colorfield.fields import ColorField from django.db import models from django.db.models import Count from django.urls import reverse +from django_ckeditor_5.fields import CKEditor5Field from drf_spectacular.utils import extend_schema_field from rest_framework import serializers @@ -16,7 +16,7 @@ class Post(BaseImageModel, ShortLinkModel, UserHistoryModel): title = models.CharField(max_length=100, blank=False) - body = RichTextUploadingField(blank=False) + body = CKEditor5Field(blank=False, config_name="extends") creator = models.ForeignKey(User, on_delete=models.CASCADE, related_name="posts") diff --git a/akarpov/music/api/permissions.py b/akarpov/music/api/permissions.py new file mode 100644 index 0000000..cdb0f80 --- /dev/null +++ b/akarpov/music/api/permissions.py @@ -0,0 +1,56 @@ +from rest_framework import permissions + +from akarpov.users.models import User, UserAPIToken + + +class GetBaseMusicPermission(permissions.BasePermission): + def get_token_data(self, request) -> (dict, User | None): + try: + token = request.headers["Authorization"] + if " " in token: + token = token.split(" ")[1] + except (KeyError, IndexError): + return { + "listen": False, + "upload": False, + "playlist": False, + }, None + try: + token = UserAPIToken.objects.cache().get(token=token) + except UserAPIToken.DoesNotExist: + return { + "listen": False, + "upload": False, + "playlist": False, + }, None + if "music" not in token.permissions: + return { + "listen": False, + "upload": False, + "playlist": False, + }, token.user + return token.permissions["music"], token.user + + +class CanListenToMusic(GetBaseMusicPermission): + def has_permission(self, request, view): + token_data = self.get_token_data(request) + if "listen" in token_data: + return token_data["listen"] + return False + + +class CanUploadMusic(GetBaseMusicPermission): + def has_permission(self, request, view): + token_data = self.get_token_data(request) + if "upload" in token_data: + return token_data["upload"] + return False + + +class CanManagePlaylists(GetBaseMusicPermission): + def has_permission(self, request, view): + token_data = self.get_token_data(request) + if "playlist" in token_data: + return token_data["playlist"] + return False diff --git a/akarpov/templates/base.html b/akarpov/templates/base.html index be67455..3f64963 100644 --- a/akarpov/templates/base.html +++ b/akarpov/templates/base.html @@ -100,6 +100,7 @@
  • Activate promocode
  • History
  • 2FA
  • +
  • API Tokens
  • @@ -139,7 +140,7 @@
    diff --git a/akarpov/templates/blog/form.html b/akarpov/templates/blog/form.html index 51dbd3e..d78c049 100644 --- a/akarpov/templates/blog/form.html +++ b/akarpov/templates/blog/form.html @@ -8,13 +8,9 @@
    {% csrf_token %} {{ form.media }} - {% for field in form %} - {{ field|as_crispy_field }} - {% endfor %} + {{ form|crispy }}
    - +
    {% endblock %} diff --git a/akarpov/templates/users/confirm_delete_token.html b/akarpov/templates/users/confirm_delete_token.html new file mode 100644 index 0000000..79fcb31 --- /dev/null +++ b/akarpov/templates/users/confirm_delete_token.html @@ -0,0 +1,12 @@ +{% extends "base.html" %} +{% block content %} +
    +

    Confirm Deletion

    +

    Are you sure you want to delete this token?

    +
    + {% csrf_token %} + + Cancel +
    +
    +{% endblock %} diff --git a/akarpov/templates/users/create_token.html b/akarpov/templates/users/create_token.html new file mode 100644 index 0000000..683f5a5 --- /dev/null +++ b/akarpov/templates/users/create_token.html @@ -0,0 +1,21 @@ +{% extends "base.html" %} +{% load crispy_forms_tags %} + +{% block content %} +
    +

    Create API Token

    +
    + {% csrf_token %} + {% for field in form %} + {% if field.name|slice:":12" == 'permissions_' %} +
    + {{ field|as_crispy_field }} +
    + {% else %} + {{ field|as_crispy_field }} + {% endif %} + {% endfor %} + +
    +
    +{% endblock %} diff --git a/akarpov/templates/users/list_tokens.html b/akarpov/templates/users/list_tokens.html new file mode 100644 index 0000000..20eb227 --- /dev/null +++ b/akarpov/templates/users/list_tokens.html @@ -0,0 +1,27 @@ +{% extends "base.html" %} +{% load humanize %} +{% block content %} +
    +

    My API Tokens

    + + +
    +{% endblock %} diff --git a/akarpov/templates/users/token_created.html b/akarpov/templates/users/token_created.html new file mode 100644 index 0000000..02b7a7d --- /dev/null +++ b/akarpov/templates/users/token_created.html @@ -0,0 +1,17 @@ +{% extends "base.html" %} +{% load static %} +{% block content %} +
    +

    Token Created Successfully

    +

    Your new API token is:

    +

    {{ new_token }}

    +

    Please note it down. You won't be able to see it again.

    + Back to Tokens +
    + + +{% endblock %} diff --git a/akarpov/templates/users/view_token.html b/akarpov/templates/users/view_token.html new file mode 100644 index 0000000..44fb316 --- /dev/null +++ b/akarpov/templates/users/view_token.html @@ -0,0 +1,26 @@ +{% extends "base.html" %} +{% block content %} +
    +

    Token Details

    + {% if token.name %} +

    Name: {{ token.name }}

    + {% endif %} +

    Token: {{ token.token|slice:":5" }}***{{ token.token|slice:"-5:" }}

    +

    Last Used: {{ token.last_used|date:"Y-m-d H:i:s" }} ({{ token.last_used|timesince }} ago)

    +

    Active Until: {{ token.active_until|date:"Y-m-d" }}

    +

    Permissions:

    + + {# Edit TODO #} + Delete +
    +{% endblock %} diff --git a/akarpov/users/admin.py b/akarpov/users/admin.py index 29bdccf..cf210cb 100644 --- a/akarpov/users/admin.py +++ b/akarpov/users/admin.py @@ -4,6 +4,7 @@ from django.utils.translation import gettext_lazy as _ from .forms import UserAdminChangeForm, UserAdminCreationForm +from .models import UserAPIToken User = get_user_model() @@ -33,3 +34,19 @@ class UserAdmin(auth_admin.UserAdmin): ) list_display = ["username", "is_superuser"] search_fields = ["username", "email"] + + +@admin.register(UserAPIToken) +class UserAPITokenAdmin(admin.ModelAdmin): + list_display = ["user", "active_until", "last_used"] + search_fields = ["user__username", "token"] + list_filter = ["active_until", "last_used"] + date_hierarchy = "active_until" + raw_id_fields = ["user"] + actions = ["deactivate_tokens"] + + def deactivate_tokens(self, request, queryset): + queryset.update(active_until=None) + self.message_user(request, _("Tokens deactivated")) + + deactivate_tokens.short_description = _("Deactivate selected tokens") diff --git a/akarpov/users/api/authentification.py b/akarpov/users/api/authentification.py new file mode 100644 index 0000000..499e138 --- /dev/null +++ b/akarpov/users/api/authentification.py @@ -0,0 +1,22 @@ +from rest_framework.authentication import BaseAuthentication + +from akarpov.users.models import UserAPIToken +from akarpov.users.tasks import set_last_active_token + + +class UserTokenAuthentication(BaseAuthentication): + def authenticate(self, request): + if "Authorization" not in request.headers: + return None + token = request.headers["Authorization"] + if " " in token: + token = token.split(" ")[1] + try: + token = UserAPIToken.objects.cache().get(token=token) + except UserAPIToken.DoesNotExist: + return None + if not token.is_active: + return None + set_last_active_token.delay(token.token) + + return token.user, token diff --git a/akarpov/users/forms.py b/akarpov/users/forms.py index a61a853..0c443bf 100644 --- a/akarpov/users/forms.py +++ b/akarpov/users/forms.py @@ -1,10 +1,15 @@ +import json + from allauth.account.forms import SignupForm from allauth.socialaccount.forms import SignupForm as SocialSignupForm from django import forms from django.contrib.auth import forms as admin_forms from django.contrib.auth import get_user_model +from django.forms import DateInput, TextInput from django.utils.translation import gettext_lazy as _ +from akarpov.users.models import UserAPIToken + User = get_user_model() @@ -45,3 +50,80 @@ class UserSocialSignupForm(SocialSignupForm): class OTPForm(forms.Form): otp_token = forms.CharField() + + +class TokenCreationForm(forms.ModelForm): + permissions = forms.MultipleChoiceField( + choices=[], # To be set in __init__ + widget=forms.CheckboxSelectMultiple, + required=False, + ) + + class Meta: + model = UserAPIToken + fields = ["name", "active_until", "permissions"] + widgets = { + "name": TextInput(attrs={"placeholder": "Token Name (Optional)"}), + "active_until": DateInput(attrs={"type": "date"}, format="%d.%m.%Y"), + } + # Make active_until not required + required = { + "active_until": False, + } + + def __init__(self, *args, **kwargs): + permissions_context = kwargs.pop("permissions_context", None) + super().__init__(*args, **kwargs) + + if permissions_context: + for app, actions in permissions_context.items(): + field_name = f"permissions_{app}" + self.fields[field_name] = forms.MultipleChoiceField( + choices=[(action, action) for action in actions.keys()], + widget=forms.CheckboxSelectMultiple, + required=False, + label=app.capitalize(), + initial=[ + item + for sublist in kwargs.get("initial", {}).get(field_name, []) + for item in sublist + ], + ) + self.fields["active_until"].required = False + + def get_permissions_choices(self): + permissions_choices = [ + (f"{app}.{action}", description) + for app, actions in UserAPIToken.permission_template.items() + for action, description in actions.items() + ] + return permissions_choices + + def clean(self): + cleaned_data = super().clean() + structured_permissions = { + category: {perm: False for perm in permissions.keys()} + for category, permissions in UserAPIToken.permission_template.items() + } + + for category in structured_permissions.keys(): + input_field_name = f"permissions_{category}" + if input_field_name in self.data: + selected_perms = self.data.getlist(input_field_name) + for perm in selected_perms: + if perm in structured_permissions[category]: + structured_permissions[category][perm] = True + + cleaned_data["permissions"] = json.dumps(structured_permissions) + + return cleaned_data + + def save(self, commit=True): + instance = super().save(commit=False) + permissions_json = self.cleaned_data.get("permissions", "{}") + instance.permissions = json.loads(permissions_json) + + if commit: + instance.save() + + return instance diff --git a/akarpov/users/middleware.py b/akarpov/users/middleware.py index a04542a..fc8c452 100644 --- a/akarpov/users/middleware.py +++ b/akarpov/users/middleware.py @@ -6,6 +6,8 @@ from django_otp.plugins.otp_totp.models import TOTPDevice from rest_framework.exceptions import AuthenticationFailed +from akarpov.users.models import UserAPIToken + class EmailVerificationMiddleware(MiddlewareMixin): def process_request(self, request): @@ -21,12 +23,20 @@ def __init__(self, get_response): def __call__(self, request): response = self.get_response(request) - if ( - request.path_info.startswith("/api/v1/music/") - or request.path_info == "/api/v1/auth/token/" - ): + if request.path_info == "/api/v1/auth/token/": return response + if "Authorization" in request.headers: + try: + token = request.headers["Authorization"] + if " " in token: + token = token.split(" ")[1] + token = UserAPIToken.objects.cache().get(token=token) + request.token_permissions = token.permissions + return response + except (KeyError, AttributeError, UserAPIToken.DoesNotExist): + ... + # Check user is authenticated and OTP token input is not completed is_authenticated = request.user.is_authenticated otp_not_verified = not request.session.get("otp_verified", False) diff --git a/akarpov/users/migrations/0015_userapitoken.py b/akarpov/users/migrations/0015_userapitoken.py new file mode 100644 index 0000000..1e83a9f --- /dev/null +++ b/akarpov/users/migrations/0015_userapitoken.py @@ -0,0 +1,40 @@ +# Generated by Django 4.2.10 on 2024-03-29 15:18 + +from django.conf import settings +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + dependencies = [ + ("users", "0014_alter_user_agree_data_to_be_sold"), + ] + + operations = [ + migrations.CreateModel( + name="UserAPIToken", + fields=[ + ( + "id", + models.BigAutoField( + auto_created=True, + primary_key=True, + serialize=False, + verbose_name="ID", + ), + ), + ("token", models.CharField(db_index=True, max_length=255, unique=True)), + ("created", models.DateTimeField(auto_now_add=True)), + ("active_until", models.DateTimeField(null=True)), + ("permissions", models.JSONField(default=dict)), + ( + "user", + models.ForeignKey( + on_delete=django.db.models.deletion.CASCADE, + related_name="api_tokens", + to=settings.AUTH_USER_MODEL, + ), + ), + ], + ), + ] diff --git a/akarpov/users/migrations/0016_userapitoken_last_used.py b/akarpov/users/migrations/0016_userapitoken_last_used.py new file mode 100644 index 0000000..0ab81ce --- /dev/null +++ b/akarpov/users/migrations/0016_userapitoken_last_used.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.10 on 2024-03-29 18:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("users", "0015_userapitoken"), + ] + + operations = [ + migrations.AddField( + model_name="userapitoken", + name="last_used", + field=models.DateTimeField(blank=True, null=True), + ), + ] diff --git a/akarpov/users/migrations/0017_userapitoken_name.py b/akarpov/users/migrations/0017_userapitoken_name.py new file mode 100644 index 0000000..1d1ed47 --- /dev/null +++ b/akarpov/users/migrations/0017_userapitoken_name.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.10 on 2024-03-29 19:31 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("users", "0016_userapitoken_last_used"), + ] + + operations = [ + migrations.AddField( + model_name="userapitoken", + name="name", + field=models.CharField(blank=True, max_length=255, null=True), + ), + ] diff --git a/akarpov/users/models.py b/akarpov/users/models.py index 3578b24..4ef13c0 100644 --- a/akarpov/users/models.py +++ b/akarpov/users/models.py @@ -1,9 +1,12 @@ +import secrets + from django.contrib.auth.models import AbstractUser from django.contrib.contenttypes.fields import GenericForeignKey from django.contrib.contenttypes.models import ContentType from django.core.validators import MinValueValidator from django.db import models from django.urls import reverse +from django.utils import timezone from django.utils.translation import gettext_lazy as _ from akarpov.common.models import BaseImageModel @@ -78,6 +81,46 @@ def __str__(self): return self -class UserNotification: - # TODO: add notification system - ... +class UserAPIToken(models.Model): + name = models.CharField(max_length=255, blank=True, null=True) + user = models.ForeignKey( + "User", related_name="api_tokens", on_delete=models.CASCADE + ) + token = models.CharField(max_length=255, unique=True, db_index=True) + created = models.DateTimeField(auto_now_add=True) + active_until = models.DateTimeField(null=True) + permissions = models.JSONField(default=dict) + last_used = models.DateTimeField(null=True, blank=True) + + permission_template = { + "music": { + "listen": "Listen to music", + "upload": "Upload music", + "playlist": "Manage playlists", + }, + "users": { + "edit": "Edit user profile", + "delete": "Delete user profile", + }, + "tools": { + "shorten": "Shorten links", + }, + "files": { + "upload": "Upload files", + "download": "Download files", + }, + } + + def __str__(self): + return self.token + + @property + def is_active(self) -> bool: + return self.active_until is None or self.active_until > timezone.now() + + @staticmethod + def generate_token(): + token = secrets.token_urlsafe(32) + while UserAPIToken.objects.filter(token=token).exists(): + token = secrets.token_urlsafe(32) + return token diff --git a/akarpov/users/tasks.py b/akarpov/users/tasks.py new file mode 100644 index 0000000..c0c8f4e --- /dev/null +++ b/akarpov/users/tasks.py @@ -0,0 +1,11 @@ +from celery import shared_task +from django.utils import timezone + +from akarpov.users.models import UserAPIToken + + +@shared_task +def set_last_active_token(token: str): + token = UserAPIToken.objects.get(token=token) + token.last_used = timezone.now() + token.save() diff --git a/akarpov/users/urls.py b/akarpov/users/urls.py index 6f662c7..60a997d 100644 --- a/akarpov/users/urls.py +++ b/akarpov/users/urls.py @@ -1,13 +1,17 @@ from django.urls import include, path from akarpov.users.views import ( + create_token, + delete_token, enable_2fa_view, enforce_otp_login, + list_tokens, user_detail_view, user_history_delete_view, user_history_view, user_redirect_view, user_update_view, + view_token, ) app_name = "users" @@ -17,7 +21,11 @@ path("update/", view=user_update_view, name="update"), path("history/", view=user_history_view, name="history"), path("history/delete", view=user_history_delete_view, name="history_delete"), - path("/", view=user_detail_view, name="detail"), + path("", view=user_detail_view, name="detail"), path("2fa/login", enforce_otp_login, name="enforce_otp_login"), path("2fa/enable", enable_2fa_view, name="enable_2fa"), + path("tokens/", list_tokens, name="list_tokens"), + path("tokens/create/", create_token, name="create_token"), + path("tokens//", view_token, name="view_token"), + path("tokens//delete/", delete_token, name="delete_token"), ] diff --git a/akarpov/users/views.py b/akarpov/users/views.py index 8bcb916..ffb17cb 100644 --- a/akarpov/users/views.py +++ b/akarpov/users/views.py @@ -5,16 +5,16 @@ from django.contrib.auth.mixins import LoginRequiredMixin from django.contrib.messages.views import SuccessMessageMixin from django.contrib.sites.shortcuts import get_current_site -from django.http import HttpResponseRedirect -from django.shortcuts import redirect, render +from django.http import HttpResponseRedirect, QueryDict +from django.shortcuts import get_object_or_404, redirect, render from django.urls import reverse, reverse_lazy from django.utils.translation import gettext_lazy as _ from django.views.generic import DetailView, ListView, RedirectView, UpdateView from django_otp import user_has_device from django_otp.plugins.otp_totp.models import TOTPDevice -from akarpov.users.forms import OTPForm -from akarpov.users.models import UserHistory +from akarpov.users.forms import OTPForm, TokenCreationForm +from akarpov.users.models import UserAPIToken, UserHistory from akarpov.users.services.history import create_history_warning_note from akarpov.users.services.two_factor import generate_qr_code from akarpov.users.themes.models import Theme @@ -203,3 +203,70 @@ def enforce_otp_login(request): else: form = OTPForm() return render(request, "users/otp_verify.html", {"form": form}) + + +@login_required +def list_tokens(request): + tokens = UserAPIToken.objects.filter(user=request.user).order_by("-last_used") + return render(request, "users/list_tokens.html", {"tokens": tokens}) + + +@login_required +def create_token(request): + initial_data = {} + + # Обработка параметров 'name' и 'active_until' + if "name" in request.GET: + initial_data["name"] = request.GET["name"] + if "active_until" in request.GET: + initial_data["active_until"] = request.GET["active_until"] + + # Создаем QueryDict для разрешений, чтобы правильно обработать повторяющиеся ключи + permissions_query_dict = QueryDict("", mutable=True) + + # Разбор параметров разрешений + permissions = request.GET.getlist("permissions") + for perm in permissions: + category, permission = perm.split(".") + permissions_query_dict.update({f"permissions_{category}": [permission]}) + + # Переводим QueryDict в обычный словарь для использования в initial + permissions_data = {key: value for key, value in permissions_query_dict.lists()} + + initial_data.update(permissions_data) + + for key, value_list in permissions_data.items(): + initial_data[key] = [item for sublist in value_list for item in sublist] + + form = TokenCreationForm( + initial=initial_data, permissions_context=UserAPIToken.permission_template + ) + if request.method == "POST": + print(request.POST) + form = TokenCreationForm(request.POST) + if form.is_valid(): + new_token = form.save(commit=False) + new_token.user = request.user + new_token.token = UserAPIToken.generate_token() + new_token.save() + token_created = new_token.token + return render( + request, "users/token_created.html", {"new_token": token_created} + ) + + return render(request, "users/create_token.html", {"form": form}) + + +@login_required +def view_token(request, token_id): + token = get_object_or_404(UserAPIToken, id=token_id, user=request.user) + return render(request, "users/view_token.html", {"token": token}) + + +@login_required +def delete_token(request, token_id): + token = get_object_or_404(UserAPIToken, id=token_id, user=request.user) + if request.method == "POST": + token.delete() + return redirect("users:list_tokens") + return render(request, "users/confirm_delete_token.html", {"token": token}) diff --git a/config/settings/base.py b/config/settings/base.py index 959f1c2..c385457 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -1,6 +1,7 @@ """ Base settings to build other settings files upon. """ + from pathlib import Path import environ @@ -78,6 +79,7 @@ "auth.permission": {"ops": "all", "timeout": 60 * 15}, "music.*": {"ops": ("fetch", "get", "list"), "timeout": 60 * 15}, "otp_totp.totpdevice": {"ops": "all", "timeout": 15 * 60}, + "users.userapitoken": {"ops": "all", "timeout": 20 * 60}, } CACHEOPS_REDIS = env.str("REDIS_URL") @@ -131,8 +133,7 @@ "rest_framework.authtoken", "corsheaders", "drf_spectacular", - "ckeditor", - "ckeditor_uploader", + "django_ckeditor_5", "colorfield", "polymorphic", "cacheops", @@ -510,6 +511,7 @@ "DEFAULT_AUTHENTICATION_CLASSES": ( "rest_framework.authentication.SessionAuthentication", "rest_framework.authentication.TokenAuthentication", + "akarpov.users.api.authentification.UserTokenAuthentication", ), "DEFAULT_PERMISSION_CLASSES": ("rest_framework.permissions.IsAuthenticated",), "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", @@ -530,24 +532,128 @@ # CKEDITOR # ------------------------------------------------------------------------------ -CKEDITOR_UPLOAD_PATH = "uploads/" -CKEDITOR_CONFIGS = { +CKEDITOR_5_UPLOAD_PATH = "uploads/" +CKEDITOR_5_CONFIGS = { "default": { - "width": "full", - "extra_plugins": [ - "autosave", - "autogrow", - "autolink", - "autoembed", - "clipboard", - "dialog", - "dialogui", + "toolbar": [ + "heading", + "|", + "bold", + "italic", + "link", + "bulletedList", + "numberedList", + "blockQuote", + "imageUpload", ], - "autosave": { - "autoLoad": True, - "delay": 60, - "NotOlderThen": 20, + }, + "extends": { + "blockToolbar": [ + "paragraph", + "heading1", + "heading2", + "heading3", + "|", + "bulletedList", + "numberedList", + "|", + "blockQuote", + ], + "toolbar": [ + "heading", + "|", + "outdent", + "indent", + "|", + "bold", + "italic", + "link", + "underline", + "strikethrough", + "code", + "subscript", + "superscript", + "highlight", + "|", + "codeBlock", + "sourceEditing", + "insertImage", + "bulletedList", + "numberedList", + "todoList", + "|", + "blockQuote", + "imageUpload", + "|", + "fontSize", + "fontFamily", + "fontColor", + "fontBackgroundColor", + "mediaEmbed", + "removeFormat", + "insertTable", + ], + "image": { + "toolbar": [ + "imageTextAlternative", + "|", + "imageStyle:alignLeft", + "imageStyle:alignRight", + "imageStyle:alignCenter", + "imageStyle:side", + "|", + ], + "styles": [ + "full", + "side", + "alignLeft", + "alignRight", + "alignCenter", + ], }, + "table": { + "contentToolbar": [ + "tableColumn", + "tableRow", + "mergeTableCells", + "tableProperties", + "tableCellProperties", + ], + }, + "heading": { + "options": [ + { + "model": "paragraph", + "title": "Paragraph", + "class": "ck-heading_paragraph", + }, + { + "model": "heading1", + "view": "h1", + "title": "Heading 1", + "class": "ck-heading_heading1", + }, + { + "model": "heading2", + "view": "h2", + "title": "Heading 2", + "class": "ck-heading_heading2", + }, + { + "model": "heading3", + "view": "h3", + "title": "Heading 3", + "class": "ck-heading_heading3", + }, + ] + }, + }, + "list": { + "properties": { + "styles": "true", + "startIndex": "true", + "reversed": "true", + } }, } diff --git a/config/urls.py b/config/urls.py index e63f2c6..04b2be6 100644 --- a/config/urls.py +++ b/config/urls.py @@ -43,7 +43,9 @@ path("forms/", include("akarpov.test_platform.urls", namespace="forms")), path("tools/", include("akarpov.tools.urls", namespace="tools")), path("gallery/", include("akarpov.gallery.urls", namespace="gallery")), - path("ckeditor/", include("ckeditor_uploader.urls")), + path( + "ckeditor5/", include("django_ckeditor_5.urls"), name="ck_editor_5_upload_file" + ), path("accounts/", include("allauth.urls")), path("accounts/login/", OTPLoginView.as_view(), name="account_login"), path("", include("akarpov.blog.urls", namespace="blog")), diff --git a/poetry.lock b/poetry.lock index f85e17a..8e91a42 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,10 +1,9 @@ -# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. [[package]] name = "aiofiles" version = "23.2.1" description = "File support for asyncio." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -16,7 +15,6 @@ files = [ name = "aiohttp" version = "3.9.3" description = "Async http client/server framework (asyncio)" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -112,7 +110,6 @@ speedups = ["Brotli", "aiodns", "brotlicffi"] name = "aiosignal" version = "1.3.1" description = "aiosignal: a list of registered asynchronous callbacks" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -127,7 +124,6 @@ frozenlist = ">=1.1.0" name = "alabaster" version = "0.7.16" description = "A light, configurable Sphinx theme" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -139,7 +135,6 @@ files = [ name = "amqp" version = "5.2.0" description = "Low-level AMQP client for Python (fork of amqplib)." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -154,7 +149,6 @@ vine = ">=5.0.0,<6.0.0" name = "amzqr" version = "0.0.1" description = "Generater for amazing QR Codes. Including Common, Artistic and Animated QR Codes." -category = "main" optional = false python-versions = ">=3" files = [ @@ -171,7 +165,6 @@ Pillow = ">=3.3.1" name = "annotated-types" version = "0.6.0" description = "Reusable constraint types to use with typing.Annotated" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -183,7 +176,6 @@ files = [ name = "anyio" version = "4.3.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -204,7 +196,6 @@ trio = ["trio (>=0.23)"] name = "appdirs" version = "1.4.4" description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" optional = false python-versions = "*" files = [ @@ -216,7 +207,6 @@ files = [ name = "argcomplete" version = "3.2.2" description = "Bash tab completion for argparse" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -231,7 +221,6 @@ test = ["coverage", "mypy", "pexpect", "ruff", "wheel"] name = "argon2-cffi" version = "21.3.0" description = "The secure Argon2 password hashing algorithm." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -251,7 +240,6 @@ tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pytest"] name = "argon2-cffi-bindings" version = "21.2.0" description = "Low-level CFFI bindings for Argon2" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -289,7 +277,6 @@ tests = ["pytest"] name = "asgiref" version = "3.7.2" description = "ASGI specs, helper code, and adapters" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -304,7 +291,6 @@ tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"] name = "astroid" version = "3.1.0" description = "An abstract syntax tree for Python with inference support." -category = "main" optional = false python-versions = ">=3.8.0" files = [ @@ -316,7 +302,6 @@ files = [ name = "asttokens" version = "2.4.1" description = "Annotate AST trees with source code positions" -category = "main" optional = false python-versions = "*" files = [ @@ -335,7 +320,6 @@ test = ["astroid (>=1,<2)", "astroid (>=2,<4)", "pytest"] name = "async-timeout" version = "4.0.3" description = "Timeout context manager for asyncio programs" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -347,7 +331,6 @@ files = [ name = "attrs" version = "23.2.0" description = "Classes Without Boilerplate" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -367,7 +350,6 @@ tests-no-zope = ["attrs[tests-mypy]", "cloudpickle", "hypothesis", "pympler", "p name = "audioread" version = "3.0.1" description = "Multi-library, cross-platform audio decoding." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -382,7 +364,6 @@ test = ["tox"] name = "autobahn" version = "23.6.2" description = "WebSocket client & server library, WAMP real-time framework" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -411,7 +392,6 @@ xbr = ["base58 (>=2.1.0)", "bitarray (>=2.7.5)", "cbor2 (>=5.2.0)", "click (>=8. name = "automat" version = "22.10.0" description = "Self-service finite-state machines for the programmer on the go." -category = "main" optional = false python-versions = "*" files = [ @@ -430,7 +410,6 @@ visualize = ["Twisted (>=16.1.1)", "graphviz (>0.5.1)"] name = "babel" version = "2.14.0" description = "Internationalization utilities" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -445,7 +424,6 @@ dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] name = "beautifulsoup4" version = "4.12.3" description = "Screen-scraping library" -category = "main" optional = false python-versions = ">=3.6.0" files = [ @@ -467,7 +445,6 @@ lxml = ["lxml"] name = "billiard" version = "4.2.0" description = "Python multiprocessing fork with improvements and bugfixes" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -479,7 +456,6 @@ files = [ name = "black" version = "23.12.1" description = "The uncompromising code formatter." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -524,7 +500,6 @@ uvloop = ["uvloop (>=0.15.2)"] name = "brotli" version = "1.1.0" description = "Python bindings for the Brotli compression library" -category = "main" optional = false python-versions = "*" files = [ @@ -617,7 +592,6 @@ files = [ name = "brotlicffi" version = "1.1.0.0" description = "Python CFFI bindings to the Brotli library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -657,7 +631,6 @@ cffi = ">=1.0.0" name = "cairocffi" version = "1.6.1" description = "cffi-based cairo bindings for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -677,7 +650,6 @@ xcb = ["xcffib (>=1.4.0)"] name = "cairosvg" version = "2.7.1" description = "A Simple SVG Converter based on Cairo" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -700,7 +672,6 @@ test = ["flake8", "isort", "pytest"] name = "celery" version = "5.3.6" description = "Distributed Task Queue." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -757,7 +728,6 @@ zstd = ["zstandard (==0.22.0)"] name = "certifi" version = "2024.2.2" description = "Python package for providing Mozilla's CA Bundle." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -769,7 +739,6 @@ files = [ name = "cffi" version = "1.16.0" description = "Foreign Function Interface for Python calling C code." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -834,7 +803,6 @@ pycparser = "*" name = "cfgv" version = "3.4.0" description = "Validate configuration and produce human readable error messages." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -846,7 +814,6 @@ files = [ name = "channels" version = "4.0.0" description = "Brings async, event-driven capabilities to Django 3.2 and up." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -867,7 +834,6 @@ tests = ["async-timeout", "coverage (>=4.5,<5.0)", "pytest", "pytest-asyncio", " name = "channels-redis" version = "4.2.0" description = "Redis-backed ASGI channel layer implementation" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -889,7 +855,6 @@ tests = ["async-timeout", "cryptography (>=1.3.0)", "pytest", "pytest-asyncio", name = "chardet" version = "5.2.0" description = "Universal encoding detector for Python 3" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -901,7 +866,6 @@ files = [ name = "charset-normalizer" version = "3.3.2" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -1001,7 +965,6 @@ files = [ name = "click" version = "8.1.7" description = "Composable command line interface toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1016,7 +979,6 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "click-didyoumean" version = "0.3.0" description = "Enables git-like *did-you-mean* feature in click" -category = "main" optional = false python-versions = ">=3.6.2,<4.0.0" files = [ @@ -1031,7 +993,6 @@ click = ">=7" name = "click-plugins" version = "1.1.1" description = "An extension module for click to enable registering CLI commands via setuptools entry-points." -category = "main" optional = false python-versions = "*" files = [ @@ -1049,7 +1010,6 @@ dev = ["coveralls", "pytest (>=3.6)", "pytest-cov", "wheel"] name = "click-repl" version = "0.3.0" description = "REPL plugin for Click" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1068,7 +1028,6 @@ testing = ["pytest (>=7.2.1)", "pytest-cov (>=4.0.0)", "tox (>=4.4.3)"] name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -1080,7 +1039,6 @@ files = [ name = "colorclass" version = "2.2.2" description = "Colorful worry-free console applications for Linux, Mac OS X, and Windows." -category = "main" optional = false python-versions = ">=2.6" files = [ @@ -1092,7 +1050,6 @@ files = [ name = "compressed-rtf" version = "1.0.6" description = "Compressed Rich Text Format (RTF) compression and decompression package" -category = "main" optional = false python-versions = "*" files = [ @@ -1103,7 +1060,6 @@ files = [ name = "constantly" version = "23.10.4" description = "Symbolic constants in Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1115,7 +1071,6 @@ files = [ name = "contourpy" version = "1.2.0" description = "Python library for calculating contours of 2D quadrilateral grids" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -1179,7 +1134,6 @@ test-no-images = ["pytest", "pytest-cov", "pytest-xdist", "wurlitzer"] name = "coverage" version = "7.4.3" description = "Code coverage measurement for Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1244,7 +1198,6 @@ toml = ["tomli"] name = "crispy-bootstrap5" version = "0.7" description = "Bootstrap5 template pack for django-crispy-forms" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1263,7 +1216,6 @@ test = ["pytest", "pytest-django"] name = "cron-descriptor" version = "1.4.3" description = "A Python library that converts cron expressions into human readable strings." -category = "main" optional = false python-versions = "*" files = [ @@ -1278,7 +1230,6 @@ dev = ["polib"] name = "cryptography" version = "42.0.5" description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1333,7 +1284,6 @@ test-randomorder = ["pytest-randomly"] name = "cssselect2" version = "0.7.0" description = "CSS selectors for Python ElementTree" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1353,7 +1303,6 @@ test = ["flake8", "isort", "pytest"] name = "cycler" version = "0.12.1" description = "Composable style cycles" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1369,7 +1318,6 @@ tests = ["pytest", "pytest-cov", "pytest-xdist"] name = "dacite" version = "1.8.1" description = "Simple creation of data classes from dictionaries." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1383,7 +1331,6 @@ dev = ["black", "coveralls", "mypy", "pre-commit", "pylint", "pytest (>=5)", "py name = "daphne" version = "4.1.0" description = "Django ASGI (HTTP/WebSocket) server" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1403,7 +1350,6 @@ tests = ["django", "hypothesis", "pytest", "pytest-asyncio"] name = "dawg-python" version = "0.7.2" description = "Pure-python reader for DAWGs (DAFSAs) created by dawgdic C++ library or DAWG Python extension." -category = "main" optional = false python-versions = "*" files = [ @@ -1415,7 +1361,6 @@ files = [ name = "decorator" version = "5.1.1" description = "Decorators for Humans" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -1427,7 +1372,6 @@ files = [ name = "deep-translator" version = "1.4.2" description = "A flexible python tool to translate between different languages in a simple way." -category = "main" optional = false python-versions = ">=3.0" files = [ @@ -1443,7 +1387,6 @@ requests = "*" name = "defusedxml" version = "0.7.1" description = "XML bomb protection for Python stdlib modules" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -1455,7 +1398,6 @@ files = [ name = "deprecated" version = "1.2.14" description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1473,7 +1415,6 @@ dev = ["PyTest", "PyTest-Cov", "bump2version (<1)", "sphinx (<2)", "tox"] name = "dill" version = "0.3.8" description = "serialize all of Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1489,7 +1430,6 @@ profile = ["gprof2dot (>=2022.7.29)"] name = "distlib" version = "0.3.8" description = "Distribution utilities" -category = "main" optional = false python-versions = "*" files = [ @@ -1501,7 +1441,6 @@ files = [ name = "django" version = "4.2.10" description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1522,7 +1461,6 @@ bcrypt = ["bcrypt"] name = "django-active-link" version = "0.1.8" description = "The best way to highlight active links in your Django app." -category = "main" optional = false python-versions = "*" files = [ @@ -1534,7 +1472,6 @@ files = [ name = "django-allauth" version = "0.54.0" description = "Integrated set of Django applications addressing authentication, registration, account management as well as 3rd party (social) account authentication." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1552,7 +1489,6 @@ requests-oauthlib = ">=0.3.0" name = "django-anymail" version = "10.2" description = "Django email backends and webhooks for Amazon SES, Brevo (Sendinblue), MailerSend, Mailgun, Mailjet, Mandrill, Postal, Postmark, Resend, SendGrid, and SparkPost" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1574,7 +1510,6 @@ resend = ["svix"] name = "django-cacheops" version = "7.0.2" description = "A slick ORM cache with automatic granular event-driven invalidation for Django." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1590,7 +1525,6 @@ redis = ">=3.0.0" name = "django-celery-beat" version = "2.5.0" description = "Database-backed Periodic Tasks." -category = "main" optional = false python-versions = "*" files = [ @@ -1607,26 +1541,27 @@ python-crontab = ">=2.3.4" tzdata = "*" [[package]] -name = "django-ckeditor" -version = "6.7.1" -description = "Django admin CKEditor integration." -category = "main" +name = "django-ckeditor-5" +version = "0.2.12" +description = "CKEditor 5 for Django." optional = false -python-versions = ">=3.8" +python-versions = ">=3.7" files = [ - {file = "django-ckeditor-6.7.1.tar.gz", hash = "sha256:7144f9ead662306266c728912487313b3b87ba2abf9dbb82c447f662ce25d1f7"}, - {file = "django_ckeditor-6.7.1-py3-none-any.whl", hash = "sha256:55b5f9ce3af47e3c8a8ed37d42be8439da2a664d6e571c2247c1db5c96459dd7"}, + {file = "django-ckeditor-5-0.2.12.tar.gz", hash = "sha256:c7165f3736f3d29dddaeda09c175903bdf3cf2b3f376c46aa5be2cc30c2c4e97"}, + {file = "django_ckeditor_5-0.2.12-py3-none-any.whl", hash = "sha256:f32cf1ce6e498d114baed8eda4b81526d61f55b55ee67ed985c26714365344e5"}, ] [package.dependencies] -Django = ">=3.2" -django-js-asset = ">=2.0" +Django = ">=2.2" +Pillow = "*" + +[package.extras] +dev = ["bandit[toml] (==1.7.6)", "black (==22.12.0)", "codespell (==2.2.2)", "coverage (==7.4.0)", "mypy (==1.8.0)", "mypy-extensions (==1.0.0)", "pytest (==7.4.4)", "pytest-cov (==4.0.0)", "pytest-django (==4.5.2)", "pytest-mock (==3.10.0)", "safety (==2.3.5)", "types-setuptools (==65.6.0.2)", "typing-extensions (==4.9.0)"] [[package]] name = "django-classy-tags" version = "4.1.0" description = "Class based template tags for Django" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1641,7 +1576,6 @@ django = ">=3.2" name = "django-colorfield" version = "0.11.0" description = "color field for django models with a nice color-picker in the admin." -category = "main" optional = false python-versions = "*" files = [ @@ -1656,7 +1590,6 @@ Pillow = ">=9.0.0" name = "django-cors-headers" version = "4.3.1" description = "django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS)." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1672,7 +1605,6 @@ Django = ">=3.2" name = "django-coverage-plugin" version = "3.1.0" description = "Django template coverage.py plugin" -category = "main" optional = false python-versions = "*" files = [ @@ -1687,7 +1619,6 @@ coverage = "*" name = "django-crispy-forms" version = "2.1" description = "Best way to have Django DRY forms" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1702,7 +1633,6 @@ django = ">=4.2" name = "django-debug-toolbar" version = "4.3.0" description = "A configurable set of panels that display various debug information about the current request/response." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1718,7 +1648,6 @@ sqlparse = ">=0.2" name = "django-elasticsearch-dsl" version = "8.0" description = "Wrapper around elasticsearch-dsl-py for django models" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1737,7 +1666,6 @@ celery = ["celery (>=4.1.0)"] name = "django-environ" version = "0.9.0" description = "A package that allows you to utilize 12factor inspired environment variables to configure your Django application." -category = "main" optional = false python-versions = ">=3.4,<4" files = [ @@ -1746,15 +1674,14 @@ files = [ ] [package.extras] -develop = ["coverage[toml] (>=5.0a4)", "furo (>=2021.8.17b43,<2021.9.0)", "pytest (>=4.6.11)", "sphinx (>=3.5.0)", "sphinx-notfound-page"] -docs = ["furo (>=2021.8.17b43,<2021.9.0)", "sphinx (>=3.5.0)", "sphinx-notfound-page"] +develop = ["coverage[toml] (>=5.0a4)", "furo (>=2021.8.17b43,<2021.9.dev0)", "pytest (>=4.6.11)", "sphinx (>=3.5.0)", "sphinx-notfound-page"] +docs = ["furo (>=2021.8.17b43,<2021.9.dev0)", "sphinx (>=3.5.0)", "sphinx-notfound-page"] testing = ["coverage[toml] (>=5.0a4)", "pytest (>=4.6.11)"] [[package]] name = "django-extensions" version = "3.2.3" description = "Extensions for Django" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1769,7 +1696,6 @@ Django = ">=3.2" name = "django-extra-settings" version = "0.9.1" description = "config and manage typed extra settings using just the django admin." -category = "main" optional = false python-versions = "*" files = [ @@ -1784,7 +1710,6 @@ jsonfield = ">=3.0.0" name = "django-filter" version = "23.5" description = "Django-filter is a reusable Django application for allowing users to filter querysets dynamically." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1799,7 +1724,6 @@ Django = ">=3.2" name = "django-health-check" version = "3.18.1" description = "Run checks on services like databases, queue servers, celery processes, etc." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1818,7 +1742,6 @@ test = ["celery", "pytest", "pytest-cov", "pytest-django", "redis"] name = "django-ipware" version = "5.0.2" description = "A Django application to retrieve user's IP address" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1830,7 +1753,6 @@ files = [ name = "django-jazzmin" version = "2.6.0" description = "Drop-in theme for django admin, that utilises AdminLTE 3 & Bootstrap 4 to make yo' admin look jazzy" -category = "main" optional = false python-versions = ">=3.6.2" files = [ @@ -1841,29 +1763,10 @@ files = [ [package.dependencies] django = ">=2.2" -[[package]] -name = "django-js-asset" -version = "2.2.0" -description = "script tag with additional attributes for django.forms.Media" -category = "main" -optional = false -python-versions = ">=3.8" -files = [ - {file = "django_js_asset-2.2.0-py3-none-any.whl", hash = "sha256:7ef3e858e13d06f10799b56eea62b1e76706f42cf4e709be4e13356bc0ae30d8"}, - {file = "django_js_asset-2.2.0.tar.gz", hash = "sha256:0c57a82cae2317e83951d956110ce847f58ff0cdc24e314dbc18b35033917e94"}, -] - -[package.dependencies] -django = ">=3.2" - -[package.extras] -tests = ["coverage"] - [[package]] name = "django-location-field" version = "2.7.3" description = "Location field for Django" -category = "main" optional = false python-versions = "*" files = [ @@ -1874,7 +1777,6 @@ files = [ name = "django-model-utils" version = "4.4.0" description = "Django model mixins and utilities" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1889,7 +1791,6 @@ Django = ">=3.2" name = "django-otp" version = "1.3.0" description = "A pluggable framework for adding two-factor authentication to Django using one-time passwords." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1907,7 +1808,6 @@ qrcode = ["qrcode"] name = "django-polymorphic" version = "3.1.0" description = "Seamless polymorphic inheritance for Django models" -category = "main" optional = false python-versions = "*" files = [ @@ -1922,7 +1822,6 @@ Django = ">=2.1" name = "django-redis" version = "5.4.0" description = "Full featured redis cache backend for Django." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1941,7 +1840,6 @@ hiredis = ["redis[hiredis] (>=3,!=4.0.0,!=4.0.1)"] name = "django-rest-auth" version = "0.9.5" description = "Create a set of REST API endpoints for Authentication and Registration" -category = "main" optional = false python-versions = "*" files = [ @@ -1960,7 +1858,6 @@ with-social = ["django-allauth (>=0.25.0)"] name = "django-robots" version = "5.0" description = "Robots exclusion application for Django, complementing Sitemaps." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1971,7 +1868,6 @@ files = [ name = "django-sekizai" version = "4.1.0" description = "Django Sekizai" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1987,7 +1883,6 @@ django-classy-tags = ">=3.0" name = "django-structlog" version = "5.3.0" description = "Structured Logging for Django" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2008,7 +1903,6 @@ celery = ["celery (>=5.1)"] name = "django-stubs" version = "1.14.0" description = "Mypy stubs for Django" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2035,7 +1929,6 @@ compatible-mypy = ["mypy (>=0.991,<1.0)"] name = "django-stubs-ext" version = "4.2.7" description = "Monkey-patching and extensions for django-stubs" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2051,7 +1944,6 @@ typing-extensions = "*" name = "django-tables2" version = "2.7.0" description = "Table/data-grid framework for Django" -category = "main" optional = false python-versions = "*" files = [ @@ -2069,7 +1961,6 @@ tablib = ["tablib"] name = "django-timezone-field" version = "6.1.0" description = "A Django app providing DB, form, and REST framework fields for zoneinfo and pytz timezone objects." -category = "main" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -2084,7 +1975,6 @@ Django = ">=3.2,<6.0" name = "django-upload-validator" version = "1.1.6" description = "A simple Django file type validator using python-magic" -category = "main" optional = false python-versions = "*" files = [ @@ -2099,7 +1989,6 @@ python-magic = "*" name = "djangorestframework" version = "3.14.0" description = "Web APIs for Django, made easy." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2115,7 +2004,6 @@ pytz = "*" name = "djangorestframework-stubs" version = "1.8.0" description = "PEP-484 stubs for django-rest-framework" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2143,7 +2031,6 @@ markdown = ["types-Markdown (>=0.1.5)"] name = "docutils" version = "0.20.1" description = "Docutils -- Python Documentation Utilities" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2155,7 +2042,6 @@ files = [ name = "docx2txt" version = "0.8" description = "A pure python-based utility to extract text and images from docx files." -category = "main" optional = false python-versions = "*" files = [ @@ -2166,7 +2052,6 @@ files = [ name = "drf-spectacular" version = "0.26.5" description = "Sane and flexible OpenAPI 3 schema generation for Django REST framework" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2190,7 +2075,6 @@ sidecar = ["drf-spectacular-sidecar"] name = "easygui" version = "0.98.3" description = "EasyGUI is a module for very simple, very easy GUI programming in Python. EasyGUI is different from other GUI generators in that EasyGUI is NOT event-driven. Instead, all GUI interactions are invoked by simple function calls." -category = "main" optional = false python-versions = "*" files = [ @@ -2202,7 +2086,6 @@ files = [ name = "ebcdic" version = "1.1.1" description = "Additional EBCDIC codecs" -category = "main" optional = false python-versions = "*" files = [ @@ -2213,7 +2096,6 @@ files = [ name = "elastic-transport" version = "8.12.0" description = "Transport classes and utilities shared among Python Elastic client libraries" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2232,7 +2114,6 @@ develop = ["aiohttp", "furo", "mock", "pytest", "pytest-asyncio", "pytest-cov", name = "elasticsearch" version = "8.12.1" description = "Python client for Elasticsearch" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2251,7 +2132,6 @@ requests = ["requests (>=2.4.0,<3.0.0)"] name = "elasticsearch-dsl" version = "8.12.0" description = "Python client for Elasticsearch" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2270,7 +2150,6 @@ develop = ["coverage", "pytest", "pytest-cov", "pytest-mock", "pytz", "sphinx (> name = "execnet" version = "2.0.2" description = "execnet: rapid multi-Python deployment" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2285,7 +2164,6 @@ testing = ["hatch", "pre-commit", "pytest", "tox"] name = "executing" version = "2.0.1" description = "Get the currently executing AST node of a frame, and other information" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2300,7 +2178,6 @@ tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipyth name = "extract-msg" version = "0.47.0" description = "Extracts emails and attachments saved in Microsoft Outlook's .msg files" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2328,7 +2205,6 @@ readthedocs = ["sphinx-rtd-theme"] name = "factory-boy" version = "3.3.0" description = "A versatile test fixtures replacement based on thoughtbot's factory_bot for Ruby." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2347,7 +2223,6 @@ doc = ["Sphinx", "sphinx-rtd-theme", "sphinxcontrib-spelling"] name = "faker" version = "23.3.0" description = "Faker is a Python package that generates fake data for you." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2362,7 +2237,6 @@ python-dateutil = ">=2.4" name = "fastapi" version = "0.103.0" description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2382,7 +2256,6 @@ all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)" name = "ffmpeg-python" version = "0.2.0" description = "Python bindings for FFmpeg - with complex filtering support" -category = "main" optional = false python-versions = "*" files = [ @@ -2400,7 +2273,6 @@ dev = ["Sphinx (==2.1.0)", "future (==0.17.1)", "numpy (==1.16.4)", "pytest (==4 name = "filelock" version = "3.13.1" description = "A platform independent file lock." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2417,7 +2289,6 @@ typing = ["typing-extensions (>=4.8)"] name = "flake8" version = "6.1.0" description = "the modular source code checker: pep8 pyflakes and co" -category = "main" optional = false python-versions = ">=3.8.1" files = [ @@ -2434,7 +2305,6 @@ pyflakes = ">=3.1.0,<3.2.0" name = "flake8-isort" version = "6.1.1" description = "flake8 plugin that integrates isort" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2453,7 +2323,6 @@ test = ["pytest"] name = "flower" version = "2.0.1" description = "Celery Flower" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2472,7 +2341,6 @@ tornado = ">=5.0.0,<7.0.0" name = "fonttools" version = "4.49.0" description = "Tools to manipulate font files" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2538,7 +2406,6 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "frozenlist" version = "1.4.1" description = "A list-like structure which implements collections.abc.MutableSequence" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2625,7 +2492,6 @@ files = [ name = "funcy" version = "2.0" description = "A fancy and practical functional tools" -category = "main" optional = false python-versions = "*" files = [ @@ -2637,7 +2503,6 @@ files = [ name = "future" version = "1.0.0" description = "Clean single-source support for Python 3 and 2" -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2649,7 +2514,6 @@ files = [ name = "fuzzywuzzy" version = "0.18.0" description = "Fuzzy string matching in python" -category = "main" optional = false python-versions = "*" files = [ @@ -2664,7 +2528,6 @@ speedup = ["python-levenshtein (>=0.12)"] name = "greenlet" version = "3.0.3" description = "Lightweight in-process concurrent programming" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2736,7 +2599,6 @@ test = ["objgraph", "psutil"] name = "gunicorn" version = "21.2.0" description = "WSGI HTTP Server for UNIX" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2757,7 +2619,6 @@ tornado = ["tornado (>=0.2)"] name = "h11" version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2769,7 +2630,6 @@ files = [ name = "hiredis" version = "2.3.2" description = "Python wrapper for hiredis" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2888,7 +2748,6 @@ files = [ name = "httpcore" version = "1.0.4" description = "A minimal low-level HTTP client." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2903,14 +2762,13 @@ h11 = ">=0.13,<0.15" [package.extras] asyncio = ["anyio (>=4.0,<5.0)"] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (>=1.0.0,<2.0.0)"] +socks = ["socksio (==1.*)"] trio = ["trio (>=0.22.0,<0.25.0)"] [[package]] name = "httpx" version = "0.27.0" description = "The next generation HTTP client." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2921,21 +2779,20 @@ files = [ [package.dependencies] anyio = "*" certifi = "*" -httpcore = ">=1.0.0,<2.0.0" +httpcore = "==1.*" idna = "*" sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] -cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<14)"] +cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (>=1.0.0,<2.0.0)"] +socks = ["socksio (==1.*)"] [[package]] name = "humanize" version = "4.9.0" description = "Python humanize utilities" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2950,7 +2807,6 @@ tests = ["freezegun", "pytest", "pytest-cov"] name = "hyperlink" version = "21.0.0" description = "A featureful, immutable, and correct URL for Python." -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -2965,7 +2821,6 @@ idna = ">=2.5" name = "identify" version = "2.5.35" description = "File identification library for Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2980,7 +2835,6 @@ license = ["ukkonen"] name = "idna" version = "3.6" description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -2992,7 +2846,6 @@ files = [ name = "imageio" version = "2.34.0" description = "Library for reading and writing a wide range of image, video, scientific, and volumetric data formats." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3025,7 +2878,6 @@ tifffile = ["tifffile"] name = "imagesize" version = "1.4.1" description = "Getting image size from png/jpeg/jpeg2000/gif file" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -3037,7 +2889,6 @@ files = [ name = "incremental" version = "22.10.0" description = "\"A small library that versions your Python projects.\"" -category = "main" optional = false python-versions = "*" files = [ @@ -3053,7 +2904,6 @@ scripts = ["click (>=6.0)", "twisted (>=16.4.0)"] name = "inflection" version = "0.5.1" description = "A port of Ruby on Rails inflector to Python" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3065,7 +2915,6 @@ files = [ name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3077,7 +2926,6 @@ files = [ name = "ipdb" version = "0.13.13" description = "IPython-enabled pdb" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -3093,7 +2941,6 @@ ipython = {version = ">=7.31.1", markers = "python_version >= \"3.11\""} name = "ipython" version = "8.22.1" description = "IPython: Productive Interactive Computing" -category = "main" optional = false python-versions = ">=3.10" files = [ @@ -3129,7 +2976,6 @@ test-extra = ["curio", "ipython[test]", "matplotlib (!=3.2.0)", "nbformat", "num name = "isort" version = "5.13.2" description = "A Python utility / library to sort Python imports." -category = "main" optional = false python-versions = ">=3.8.0" files = [ @@ -3144,7 +2990,6 @@ colors = ["colorama (>=0.4.6)"] name = "jaconv" version = "0.3.4" description = "Pure-Python Japanese character interconverter for Hiragana, Katakana, Hankaku, Zenkaku and more" -category = "main" optional = false python-versions = "*" files = [ @@ -3155,7 +3000,6 @@ files = [ name = "jedi" version = "0.19.1" description = "An autocompletion tool for Python that can be used for text editors." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3175,7 +3019,6 @@ testing = ["Django", "attrs", "colorama", "docopt", "pytest (<7.0.0)"] name = "jinja2" version = "3.1.3" description = "A very fast and expressive template engine." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3193,7 +3036,6 @@ i18n = ["Babel (>=2.7)"] name = "joblib" version = "1.3.2" description = "Lightweight pipelining with Python functions" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3205,7 +3047,6 @@ files = [ name = "jsonfield" version = "3.1.0" description = "A reusable Django field that allows you to store validated JSON in your model." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3220,7 +3061,6 @@ Django = ">=2.2" name = "jsonschema" version = "4.21.1" description = "An implementation of JSON Schema validation for Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3242,7 +3082,6 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "jsonschema-specifications" version = "2023.12.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3257,7 +3096,6 @@ referencing = ">=0.31.0" name = "kiwisolver" version = "1.4.5" description = "A fast implementation of the Cassowary constraint solver" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3371,7 +3209,6 @@ files = [ name = "kombu" version = "5.3.5" description = "Messaging library for Python." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3404,7 +3241,6 @@ zookeeper = ["kazoo (>=2.8.0)"] name = "lark" version = "1.1.8" description = "a modern parsing library" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3422,7 +3258,6 @@ regex = ["regex"] name = "lazy-loader" version = "0.3" description = "lazy_loader" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3438,7 +3273,6 @@ test = ["pytest (>=7.4)", "pytest-cov (>=4.1)"] name = "levenshtein" version = "0.23.0" description = "Python extension for computing string edit distances and similarities." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3559,7 +3393,6 @@ rapidfuzz = ">=3.1.0,<4.0.0" name = "librosa" version = "0.10.1" description = "Python module for audio and music processing" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3591,7 +3424,6 @@ tests = ["matplotlib (>=3.3.0)", "packaging (>=20.0)", "pytest", "pytest-cov", " name = "livereload" version = "2.6.3" description = "Python LiveReload is an awesome tool for web developers" -category = "main" optional = false python-versions = "*" files = [ @@ -3607,7 +3439,6 @@ tornado = {version = "*", markers = "python_version > \"2.7\""} name = "llvmlite" version = "0.42.0" description = "lightweight wrapper around basic LLVM functionality" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -3638,7 +3469,6 @@ files = [ name = "lxml" version = "5.1.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3732,7 +3562,6 @@ source = ["Cython (>=3.0.7)"] name = "mako" version = "1.3.2" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3752,7 +3581,6 @@ testing = ["pytest"] name = "markdown" version = "3.5.2" description = "Python implementation of John Gruber's Markdown." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3768,7 +3596,6 @@ testing = ["coverage", "pyyaml"] name = "markdown-it-py" version = "3.0.0" description = "Python port of markdown-it. Markdown parsing, done right!" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -3793,7 +3620,6 @@ testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] name = "markupsafe" version = "2.1.5" description = "Safely add untrusted strings to HTML/XML markup." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3863,7 +3689,6 @@ files = [ name = "matplotlib" version = "3.8.3" description = "Python plotting package" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -3912,7 +3737,6 @@ python-dateutil = ">=2.7" name = "matplotlib-inline" version = "0.1.6" description = "Inline Matplotlib backend for Jupyter" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -3927,7 +3751,6 @@ traitlets = "*" name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -3939,7 +3762,6 @@ files = [ name = "mdurl" version = "0.1.2" description = "Markdown URL utilities" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -3951,7 +3773,6 @@ files = [ name = "msgpack" version = "1.0.8" description = "MessagePack serializer" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4011,13 +3832,13 @@ files = [ {file = "msgpack-1.0.8-cp39-cp39-win32.whl", hash = "sha256:f9af38a89b6a5c04b7d18c492c8ccf2aee7048aff1ce8437c4683bb5a1df893d"}, {file = "msgpack-1.0.8-cp39-cp39-win_amd64.whl", hash = "sha256:ed59dd52075f8fc91da6053b12e8c89e37aa043f8986efd89e61fae69dc1b011"}, {file = "msgpack-1.0.8-py3-none-any.whl", hash = "sha256:24f727df1e20b9876fa6e95f840a2a2651e34c0ad147676356f4bf5fbb0206ca"}, + {file = "msgpack-1.0.8.tar.gz", hash = "sha256:95c02b0e27e706e48d0e5426d1710ca78e0f0628d6e89d5b5a5b91a5f12274f3"}, ] [[package]] name = "msoffcrypto-tool" version = "5.3.1" description = "Python tool and library for decrypting MS Office files with passwords or other keys" -category = "main" optional = false python-versions = ">=3.8,<4.0" files = [ @@ -4033,7 +3854,6 @@ olefile = ">=0.46" name = "multidict" version = "6.0.5" description = "multidict implementation" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4133,7 +3953,6 @@ files = [ name = "mutagen" version = "1.47.0" description = "read and write audio tags for many formats" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4145,7 +3964,6 @@ files = [ name = "mypy" version = "0.991" description = "Optional static typing for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4195,7 +4013,6 @@ reports = ["lxml"] name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -4207,7 +4024,6 @@ files = [ name = "nltk" version = "3.8.1" description = "Natural Language Toolkit" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4233,7 +4049,6 @@ twitter = ["twython"] name = "nodeenv" version = "1.8.0" description = "Node.js virtual environment builder" -category = "main" optional = false python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*" files = [ @@ -4248,7 +4063,6 @@ setuptools = "*" name = "numba" version = "0.59.0" description = "compiling Python code using LLVM" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -4276,14 +4090,13 @@ files = [ ] [package.dependencies] -llvmlite = ">=0.42.0dev0,<0.43" +llvmlite = "==0.42.*" numpy = ">=1.22,<1.27" [[package]] name = "numpy" version = "1.25.2" description = "Fundamental package for array computing in Python" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -4318,7 +4131,6 @@ files = [ name = "oauthlib" version = "3.2.2" description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4335,7 +4147,6 @@ signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"] name = "olefile" version = "0.47" description = "Python package to parse, read and write Microsoft OLE2 files (Structured Storage or Compound Document, Microsoft Office)" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -4350,7 +4161,6 @@ tests = ["pytest", "pytest-cov"] name = "oletools" version = "0.60.1" description = "Python tools to analyze security characteristics of MS Office and OLE files (also called Structured Storage, Compound File Binary Format or Compound Document File Format), for Malware Analysis and Incident Response #DFIR" -category = "main" optional = false python-versions = "*" files = [ @@ -4361,7 +4171,7 @@ files = [ [package.dependencies] colorclass = "*" easygui = "*" -msoffcrypto-tool = {version = "*", markers = "platform_python_implementation != \"PyPy\" or python_version >= \"3\" and platform_system != \"Windows\" and platform_system != \"Darwin\""} +msoffcrypto-tool = {version = "*", markers = "platform_python_implementation != \"PyPy\" or python_version >= \"3\" and (platform_system != \"Windows\" and platform_system != \"Darwin\")"} olefile = ">=0.46" pcodedmp = ">=1.2.5" pyparsing = ">=2.1.0,<3" @@ -4373,7 +4183,6 @@ full = ["XLMMacroDeobfuscator"] name = "packaging" version = "23.2" description = "Core utilities for Python packages" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4385,7 +4194,6 @@ files = [ name = "parso" version = "0.8.3" description = "A Python Parser" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4401,7 +4209,6 @@ testing = ["docopt", "pytest (<6.0.0)"] name = "pathspec" version = "0.12.1" description = "Utility library for gitignore style pattern matching of file paths." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4413,7 +4220,6 @@ files = [ name = "pcodedmp" version = "1.2.6" description = "A VBA p-code disassembler" -category = "main" optional = false python-versions = "*" files = [ @@ -4429,7 +4235,6 @@ win-unicode-console = {version = "*", markers = "platform_system == \"Windows\" name = "pdfminer-six" version = "20221105" description = "PDF parser and analyzer" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -4450,7 +4255,6 @@ image = ["Pillow"] name = "pexpect" version = "4.9.0" description = "Pexpect allows easy control of interactive console applications." -category = "main" optional = false python-versions = "*" files = [ @@ -4465,7 +4269,6 @@ ptyprocess = ">=0.5" name = "pgvector" version = "0.2.5" description = "pgvector support for Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4479,7 +4282,6 @@ numpy = "*" name = "pillow" version = "10.2.0" description = "Python Imaging Library (Fork)" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4565,7 +4367,6 @@ xmp = ["defusedxml"] name = "platformdirs" version = "3.11.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4581,7 +4382,6 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co name = "pluggy" version = "1.4.0" description = "plugin and hook calling mechanisms for python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4597,7 +4397,6 @@ testing = ["pytest", "pytest-benchmark"] name = "pooch" version = "1.8.1" description = "\"Pooch manages your Python library's sample data files: it automatically downloads and stores them in a local directory, with support for versioning and corruption checks.\"" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4619,7 +4418,6 @@ xxhash = ["xxhash (>=1.4.3)"] name = "pre-commit" version = "3.6.2" description = "A framework for managing and maintaining multi-language pre-commit hooks." -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -4638,7 +4436,6 @@ virtualenv = ">=20.10.0" name = "preview-generator" version = "0.29" description = "A library for generating preview (thumbnails, text or json overview) for file-based content" -category = "main" optional = false python-versions = ">= 3.7" files = [ @@ -4666,7 +4463,6 @@ video = ["ffmpeg-python"] name = "prometheus-client" version = "0.20.0" description = "Python client for the Prometheus monitoring system." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4681,7 +4477,6 @@ twisted = ["twisted"] name = "prompt-toolkit" version = "3.0.43" description = "Library for building powerful interactive command lines in Python" -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -4696,7 +4491,6 @@ wcwidth = "*" name = "psutil" version = "5.9.8" description = "Cross-platform lib for process and system monitoring in Python." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -4725,7 +4519,6 @@ test = ["enum34", "ipaddress", "mock", "pywin32", "wmi"] name = "psycopg2-binary" version = "2.9.9" description = "psycopg2 - Python-PostgreSQL Database Adapter" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -4755,6 +4548,7 @@ files = [ {file = "psycopg2_binary-2.9.9-cp311-cp311-win32.whl", hash = "sha256:dc4926288b2a3e9fd7b50dc6a1909a13bbdadfc67d93f3374d984e56f885579d"}, {file = "psycopg2_binary-2.9.9-cp311-cp311-win_amd64.whl", hash = "sha256:b76bedd166805480ab069612119ea636f5ab8f8771e640ae103e05a4aae3e417"}, {file = "psycopg2_binary-2.9.9-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:8532fd6e6e2dc57bcb3bc90b079c60de896d2128c5d9d6f24a63875a95a088cf"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b0605eaed3eb239e87df0d5e3c6489daae3f7388d455d0c0b4df899519c6a38d"}, {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f8544b092a29a6ddd72f3556a9fcf249ec412e10ad28be6a0c0d948924f2212"}, {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2d423c8d8a3c82d08fe8af900ad5b613ce3632a1249fd6a223941d0735fce493"}, {file = "psycopg2_binary-2.9.9-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2e5afae772c00980525f6d6ecf7cbca55676296b580c0e6abb407f15f3706996"}, @@ -4763,6 +4557,8 @@ files = [ {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:cb16c65dcb648d0a43a2521f2f0a2300f40639f6f8c1ecbc662141e4e3e1ee07"}, {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_ppc64le.whl", hash = "sha256:911dda9c487075abd54e644ccdf5e5c16773470a6a5d3826fda76699410066fb"}, {file = "psycopg2_binary-2.9.9-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:57fede879f08d23c85140a360c6a77709113efd1c993923c59fde17aa27599fe"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-win32.whl", hash = "sha256:64cf30263844fa208851ebb13b0732ce674d8ec6a0c86a4e160495d299ba3c93"}, + {file = "psycopg2_binary-2.9.9-cp312-cp312-win_amd64.whl", hash = "sha256:81ff62668af011f9a48787564ab7eded4e9fb17a4a6a74af5ffa6a457400d2ab"}, {file = "psycopg2_binary-2.9.9-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:2293b001e319ab0d869d660a704942c9e2cce19745262a8aba2115ef41a0a42a"}, {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:03ef7df18daf2c4c07e2695e8cfd5ee7f748a1d54d802330985a78d2a5a6dca9"}, {file = "psycopg2_binary-2.9.9-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0a602ea5aff39bb9fac6308e9c9d82b9a35c2bf288e184a816002c9fae930b77"}, @@ -4804,7 +4600,6 @@ files = [ name = "ptyprocess" version = "0.7.0" description = "Run a subprocess in a pseudo terminal" -category = "main" optional = false python-versions = "*" files = [ @@ -4816,7 +4611,6 @@ files = [ name = "pure-eval" version = "0.2.2" description = "Safely evaluate AST nodes without side effects" -category = "main" optional = false python-versions = "*" files = [ @@ -4831,7 +4625,6 @@ tests = ["pytest"] name = "pyasn1" version = "0.5.1" description = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -4843,7 +4636,6 @@ files = [ name = "pyasn1-modules" version = "0.3.0" description = "A collection of ASN.1-based protocols modules" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" files = [ @@ -4858,7 +4650,6 @@ pyasn1 = ">=0.4.6,<0.6.0" name = "pycld2" version = "0.41" description = "Python bindings around Google Chromium's embedded compact language detection library (CLD2)" -category = "main" optional = false python-versions = "*" files = [ @@ -4869,7 +4660,6 @@ files = [ name = "pycodestyle" version = "2.11.1" description = "Python style guide checker" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4881,7 +4671,6 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -4893,7 +4682,6 @@ files = [ name = "pycryptodomex" version = "3.20.0" description = "Cryptographic library for Python" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -4935,7 +4723,6 @@ files = [ name = "pydantic" version = "2.6.3" description = "Data validation using Python type hints" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -4955,7 +4742,6 @@ email = ["email-validator (>=2.0.0)"] name = "pydantic-core" version = "2.16.3" description = "" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5047,7 +4833,6 @@ typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" name = "pydantic-settings" version = "2.2.1" description = "Settings management using Pydantic" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5067,7 +4852,6 @@ yaml = ["pyyaml (>=6.0.1)"] name = "pydotplus" version = "2.0.2" description = "Python interface to Graphviz's Dot language" -category = "main" optional = false python-versions = "*" files = [ @@ -5081,7 +4865,6 @@ pyparsing = ">=2.0.1" name = "pydub" version = "0.25.1" description = "Manipulate audio with an simple and easy high level interface" -category = "main" optional = false python-versions = "*" files = [ @@ -5093,7 +4876,6 @@ files = [ name = "pyexifinfo" version = "0.4.0" description = "Simple Metadata extraction using Exiftool" -category = "main" optional = false python-versions = "*" files = [ @@ -5104,7 +4886,6 @@ files = [ name = "pyflakes" version = "3.1.0" description = "passive checker of Python programs" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5116,7 +4897,6 @@ files = [ name = "pygments" version = "2.17.2" description = "Pygments is a syntax highlighting package written in Python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5132,7 +4912,6 @@ windows-terminal = ["colorama (>=0.4.6)"] name = "pyjwt" version = "2.8.0" description = "JSON Web Token implementation in Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5153,7 +4932,6 @@ tests = ["coverage[toml] (==5.0.4)", "pytest (>=6.0.0,<7.0.0)"] name = "pykakasi" version = "2.2.1" description = "Kana kanji simple inversion library" -category = "main" optional = false python-versions = "*" files = [ @@ -5174,7 +4952,6 @@ test = ["coverage[toml] (>=5.2)", "py-cpuinfo", "pytest", "pytest-benchmark", "p name = "pylast" version = "5.2.0" description = "A Python interface to Last.fm and Libre.fm" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5192,7 +4969,6 @@ tests = ["flaky", "pytest", "pytest-cov", "pytest-random-order", "pyyaml"] name = "pylint" version = "3.1.0" description = "python code static checker" -category = "main" optional = false python-versions = ">=3.8.0" files = [ @@ -5204,8 +4980,8 @@ files = [ astroid = ">=3.1.0,<=3.2.0-dev0" colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} dill = [ - {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, + {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, ] isort = ">=4.2.5,<5.13.0 || >5.13.0,<6" mccabe = ">=0.6,<0.8" @@ -5220,7 +4996,6 @@ testutils = ["gitpython (>3)"] name = "pylint-celery" version = "0.3" description = "pylint-celery is a Pylint plugin to aid Pylint in recognising and understandingerrors caused when using the Celery library" -category = "main" optional = false python-versions = "*" files = [ @@ -5236,7 +5011,6 @@ pylint-plugin-utils = ">=0.2.1" name = "pylint-django" version = "2.5.5" description = "A Pylint plugin to help Pylint understand the Django web framework" -category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -5255,7 +5029,6 @@ with-django = ["Django (>=2.2)"] name = "pylint-plugin-utils" version = "0.8.2" description = "Utilities and helpers for writing Pylint plugins" -category = "main" optional = false python-versions = ">=3.7,<4.0" files = [ @@ -5270,7 +5043,6 @@ pylint = ">=1.7" name = "pymorphy3" version = "1.3.1" description = "Morphological analyzer (POS tagger + inflection engine) for Russian language." -category = "main" optional = false python-versions = "*" files = [ @@ -5291,7 +5063,6 @@ fast = ["DAWG (>=0.8)"] name = "pymorphy3-dicts-ru" version = "2.4.417150.4580142" description = "Russian dictionaries for pymorphy2" -category = "main" optional = false python-versions = "*" files = [ @@ -5303,7 +5074,6 @@ files = [ name = "pyopenssl" version = "24.0.0" description = "Python wrapper module around the OpenSSL library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5322,7 +5092,6 @@ test = ["flaky", "pretend", "pytest (>=3.0.1)"] name = "pyparsing" version = "2.4.7" description = "Python parsing module" -category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -5334,7 +5103,6 @@ files = [ name = "pypng" version = "0.20220715.0" description = "Pure Python library for saving and loading PNG images" -category = "main" optional = false python-versions = "*" files = [ @@ -5346,7 +5114,6 @@ files = [ name = "pysocks" version = "1.7.1" description = "A Python SOCKS client module. See https://github.com/Anorov/PySocks for more information." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -5359,7 +5126,6 @@ files = [ name = "pytest" version = "7.4.4" description = "pytest: simple powerful testing with Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5380,7 +5146,6 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-asyncio" version = "0.21.1" description = "Pytest support for asyncio" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5399,7 +5164,6 @@ testing = ["coverage (>=6.2)", "flaky (>=3.5.0)", "hypothesis (>=5.7.1)", "mypy name = "pytest-django" version = "4.8.0" description = "A Django plugin for pytest." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5418,7 +5182,6 @@ testing = ["Django", "django-configurations (>=2.0)"] name = "pytest-factoryboy" version = "2.3.1" description = "Factory Boy support for pytest." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5438,7 +5201,6 @@ typing-extensions = "*" name = "pytest-lambda" version = "2.2.0" description = "Define pytest fixtures with lambda functions." -category = "main" optional = false python-versions = ">=3.7.0,<4.0.0" files = [ @@ -5454,7 +5216,6 @@ wrapt = ">=1.11.0,<2.0.0" name = "pytest-mock" version = "3.12.0" description = "Thin-wrapper around the mock package for easier use with pytest" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5472,7 +5233,6 @@ dev = ["pre-commit", "pytest-asyncio", "tox"] name = "pytest-sugar" version = "0.9.7" description = "pytest-sugar is a plugin for pytest that changes the default look and feel of pytest (e.g. progressbar, show tests that fail instantly)." -category = "main" optional = false python-versions = "*" files = [ @@ -5492,7 +5252,6 @@ dev = ["black", "flake8", "pre-commit"] name = "pytest-xdist" version = "3.5.0" description = "pytest xdist plugin for distributed testing, most importantly across multiple CPUs" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5513,7 +5272,6 @@ testing = ["filelock"] name = "python-crontab" version = "3.0.0" description = "Python Crontab API" -category = "main" optional = false python-versions = "*" files = [ @@ -5532,7 +5290,6 @@ cron-schedule = ["croniter"] name = "python-dateutil" version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" -category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -5547,7 +5304,6 @@ six = ">=1.5" name = "python-dotenv" version = "1.0.1" description = "Read key-value pairs from a .env file and set them as environment variables" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5562,7 +5318,6 @@ cli = ["click (>=5.0)"] name = "python-levenshtein" version = "0.23.0" description = "Python extension for computing string edit distances and similarities." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5577,7 +5332,6 @@ Levenshtein = "0.23.0" name = "python-magic" version = "0.4.27" description = "File type identification using libmagic" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" files = [ @@ -5589,7 +5343,6 @@ files = [ name = "python-mpd2" version = "3.1.1" description = "A Python MPD client library" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -5604,7 +5357,6 @@ twisted = ["Twisted"] name = "python-pptx" version = "0.6.23" description = "Generate and manipulate Open XML PowerPoint (.pptx) files" -category = "main" optional = false python-versions = "*" files = [ @@ -5621,7 +5373,6 @@ XlsxWriter = ">=0.5.7" name = "python-slugify" version = "8.0.1" description = "A Python slugify application that also handles Unicode" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5640,7 +5391,6 @@ unidecode = ["Unidecode (>=1.1.1)"] name = "python3-openid" version = "3.2.0" description = "OpenID support for modern servers and consumers." -category = "main" optional = false python-versions = "*" files = [ @@ -5659,7 +5409,6 @@ postgresql = ["psycopg2"] name = "pytube" version = "15.0.0" description = "Python 3 library for downloading YouTube Videos." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5671,7 +5420,6 @@ files = [ name = "pytz" version = "2023.4" description = "World timezone definitions, modern and historical" -category = "main" optional = false python-versions = "*" files = [ @@ -5683,7 +5431,6 @@ files = [ name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -5733,7 +5480,6 @@ files = [ name = "qrcode" version = "7.4.2" description = "QR Code image generator" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5758,7 +5504,6 @@ test = ["coverage", "pytest"] name = "rapidfuzz" version = "3.6.1" description = "rapid fuzzy string matching" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5861,7 +5606,6 @@ full = ["numpy"] name = "rawpy" version = "0.19.1" description = "RAW image processing for Python, a wrapper for libraw" -category = "main" optional = false python-versions = "*" files = [ @@ -5897,7 +5641,6 @@ numpy = "*" name = "red-black-tree-mod" version = "1.20" description = "Flexible python implementation of red black trees" -category = "main" optional = false python-versions = "*" files = [ @@ -5908,7 +5651,6 @@ files = [ name = "redis" version = "4.6.0" description = "Python client for Redis database and key-value store" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -5927,7 +5669,6 @@ ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)" name = "referencing" version = "0.33.0" description = "JSON Referencing + Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -5943,7 +5684,6 @@ rpds-py = ">=0.7.0" name = "regex" version = "2023.12.25" description = "Alternative regular expression module, to replace re." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6046,7 +5786,6 @@ files = [ name = "requests" version = "2.31.0" description = "Python HTTP for Humans." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6069,7 +5808,6 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "requests-oauthlib" version = "1.3.1" description = "OAuthlib authentication support for Requests." -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -6088,7 +5826,6 @@ rsa = ["oauthlib[signedtoken] (>=3.0.0)"] name = "rich" version = "13.7.1" description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -6107,7 +5844,6 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"] name = "rpds-py" version = "0.18.0" description = "Python bindings to Rust's persistent data structures (rpds)" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -6216,7 +5952,6 @@ files = [ name = "rtfde" version = "0.1.1" description = "A library for extracting HTML content from RTF encapsulated HTML as commonly found in the exchange MSG email format." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -6236,7 +5971,6 @@ msg-parse = ["extract-msg (>=0.27)"] name = "scikit-learn" version = "1.4.1.post1" description = "A set of python modules for machine learning and data mining" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -6279,7 +6013,6 @@ tests = ["black (>=23.3.0)", "matplotlib (>=3.3.4)", "mypy (>=1.3)", "numpydoc ( name = "scipy" version = "1.12.0" description = "Fundamental algorithms for scientific computing in Python" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -6322,7 +6055,6 @@ test = ["asv", "gmpy2", "hypothesis", "mpmath", "pooch", "pytest", "pytest-cov", name = "sentry-sdk" version = "1.40.6" description = "Python client for Sentry (https://sentry.io)" -category = "main" optional = false python-versions = "*" files = [ @@ -6368,7 +6100,6 @@ tornado = ["tornado (>=5)"] name = "service-identity" version = "24.1.0" description = "Service identity verification for pyOpenSSL & cryptography." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -6393,7 +6124,6 @@ tests = ["coverage[toml] (>=5.0.2)", "pytest"] name = "setuptools" version = "69.1.1" description = "Easily download, build, install, upgrade, and uninstall Python packages" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -6410,7 +6140,6 @@ testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jar name = "six" version = "1.15.0" description = "Python 2 and 3 compatibility utilities" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -6422,7 +6151,6 @@ files = [ name = "sniffio" version = "1.3.1" description = "Sniff out which async library your code is running under" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6434,7 +6162,6 @@ files = [ name = "snowballstemmer" version = "2.2.0" description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "main" optional = false python-versions = "*" files = [ @@ -6446,7 +6173,6 @@ files = [ name = "soundcloud-v2" version = "1.3.1" description = "Python wrapper for the v2 SoundCloud API" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -6466,7 +6192,6 @@ test = ["coveralls", "pytest", "pytest-dotenv"] name = "soundfile" version = "0.12.1" description = "An audio library based on libsndfile, CFFI and NumPy" -category = "main" optional = false python-versions = "*" files = [ @@ -6490,7 +6215,6 @@ numpy = ["numpy"] name = "soupsieve" version = "2.5" description = "A modern CSS selector implementation for Beautiful Soup." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -6502,7 +6226,6 @@ files = [ name = "soxr" version = "0.3.7" description = "High quality, one-dimensional sample-rate conversion library" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -6549,7 +6272,6 @@ test = ["pytest"] name = "speechrecognition" version = "3.10.1" description = "Library for performing speech recognition, with support for several engines and APIs, online and offline." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -6568,7 +6290,6 @@ whisper-api = ["openai"] name = "sphinx" version = "7.2.6" description = "Python documentation generator" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -6603,7 +6324,6 @@ test = ["cython (>=3.0)", "filelock", "html5lib", "pytest (>=4.6)", "setuptools name = "sphinx-autobuild" version = "2021.3.14" description = "Rebuild Sphinx documentation on changes, with live-reload in the browser." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -6623,7 +6343,6 @@ test = ["pytest", "pytest-cov"] name = "sphinxcontrib-applehelp" version = "1.0.8" description = "sphinxcontrib-applehelp is a Sphinx extension which outputs Apple help books" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -6640,7 +6359,6 @@ test = ["pytest"] name = "sphinxcontrib-devhelp" version = "1.0.6" description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp documents" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -6657,7 +6375,6 @@ test = ["pytest"] name = "sphinxcontrib-htmlhelp" version = "2.0.5" description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -6674,7 +6391,6 @@ test = ["html5lib", "pytest"] name = "sphinxcontrib-jsmath" version = "1.0.1" description = "A sphinx extension which renders display math in HTML via JavaScript" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -6689,7 +6405,6 @@ test = ["flake8", "mypy", "pytest"] name = "sphinxcontrib-qthelp" version = "1.0.7" description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp documents" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -6706,7 +6421,6 @@ test = ["pytest"] name = "sphinxcontrib-serializinghtml" version = "1.1.10" description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)" -category = "main" optional = false python-versions = ">=3.9" files = [ @@ -6723,7 +6437,6 @@ test = ["pytest"] name = "spotdl" version = "4.2.4" description = "Download your Spotify playlists and songs along with album art and metadata" -category = "main" optional = false python-versions = ">=3.8,<3.13" files = [ @@ -6755,7 +6468,6 @@ ytmusicapi = ">=1.3.2,<2.0.0" name = "spotipy" version = "2.23.0" description = "A light weight Python library for the Spotify Web API" -category = "main" optional = false python-versions = "*" files = [ @@ -6778,7 +6490,6 @@ test = ["mock (==2.0.0)"] name = "sqlalchemy" version = "2.0.27" description = "Database Abstraction Library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6866,7 +6577,6 @@ sqlcipher = ["sqlcipher3_binary"] name = "sqlparse" version = "0.4.4" description = "A non-validating SQL parser." -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -6883,7 +6593,6 @@ test = ["pytest", "pytest-cov"] name = "stack-data" version = "0.6.3" description = "Extract data from python stack frames and tracebacks for informative displays" -category = "main" optional = false python-versions = "*" files = [ @@ -6903,7 +6612,6 @@ tests = ["cython", "littleutils", "pygments", "pytest", "typeguard"] name = "starlette" version = "0.27.0" description = "The little ASGI library that shines." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -6921,7 +6629,6 @@ full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart", "pyyam name = "structlog" version = "24.1.0" description = "Structured Logging for Python" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -6939,7 +6646,6 @@ typing = ["mypy (>=1.4)", "rich", "twisted"] name = "syncedlyrics" version = "0.7.0" description = "Get an LRC format (synchronized) lyrics for your music" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -6956,7 +6662,6 @@ requests = ">=2.31.0,<3.0.0" name = "tablib" version = "3.5.0" description = "Format agnostic tabular data library (XLS, JSON, YAML, CSV, etc.)" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -6978,7 +6683,6 @@ yaml = ["pyyaml"] name = "termcolor" version = "2.4.0" description = "ANSI color formatting for output in terminal" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -6993,7 +6697,6 @@ tests = ["pytest", "pytest-cov"] name = "text-unidecode" version = "1.3" description = "The most basic Text::Unidecode port" -category = "main" optional = false python-versions = "*" files = [ @@ -7005,7 +6708,6 @@ files = [ name = "textract" version = "1.6.5" description = "extract text from any document. no muss. no fuss." -category = "main" optional = false python-versions = "*" files = [] @@ -7036,7 +6738,6 @@ resolved_reference = "c8c5729f8baea372a2a44cab1755be13457a1b4b" name = "threadpoolctl" version = "3.3.0" description = "threadpoolctl" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7048,7 +6749,6 @@ files = [ name = "tinycss2" version = "1.2.1" description = "A tiny CSS parser" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7067,7 +6767,6 @@ test = ["flake8", "isort", "pytest"] name = "tomli" version = "2.0.1" description = "A lil' TOML parser" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7079,7 +6778,6 @@ files = [ name = "tomlkit" version = "0.12.4" description = "Style preserving TOML library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7091,7 +6789,6 @@ files = [ name = "tornado" version = "6.4" description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -category = "main" optional = false python-versions = ">= 3.8" files = [ @@ -7112,7 +6809,6 @@ files = [ name = "tqdm" version = "4.66.2" description = "Fast, Extensible Progress Meter" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7133,7 +6829,6 @@ telegram = ["requests"] name = "traitlets" version = "5.14.1" description = "Traitlets Python configuration system" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7149,7 +6844,6 @@ test = ["argcomplete (>=3.0.3)", "mypy (>=1.7.0)", "pre-commit", "pytest (>=7.0, name = "twisted" version = "24.3.0" description = "An asynchronous networking framework written in Python" -category = "main" optional = false python-versions = ">=3.8.0" files = [ @@ -7189,7 +6883,6 @@ windows-platform = ["pywin32 (!=226)", "pywin32 (!=226)", "twisted[all-non-platf name = "twisted-iocpsupport" version = "1.0.4" description = "An extension for use in the twisted I/O Completion Ports reactor." -category = "main" optional = false python-versions = "*" files = [ @@ -7218,7 +6911,6 @@ files = [ name = "txaio" version = "23.1.1" description = "Compatibility API between asyncio/Twisted/Trollius" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7235,7 +6927,6 @@ twisted = ["twisted (>=20.3.0)", "zope.interface (>=5.2.0)"] name = "types-pytz" version = "2024.1.0.20240203" description = "Typing stubs for pytz" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7247,7 +6938,6 @@ files = [ name = "types-pyyaml" version = "6.0.12.12" description = "Typing stubs for PyYAML" -category = "main" optional = false python-versions = "*" files = [ @@ -7259,7 +6949,6 @@ files = [ name = "types-requests" version = "2.31.0.20240218" description = "Typing stubs for requests" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7274,7 +6963,6 @@ urllib3 = ">=2" name = "typing-extensions" version = "4.10.0" description = "Backported and Experimental Type Hints for Python 3.8+" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7286,7 +6974,6 @@ files = [ name = "tzdata" version = "2024.1" description = "Provider of IANA time zone data" -category = "main" optional = false python-versions = ">=2" files = [ @@ -7298,7 +6985,6 @@ files = [ name = "tzlocal" version = "5.2" description = "tzinfo object for the local timezone" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7316,7 +7002,6 @@ devenv = ["check-manifest", "pytest (>=4.3)", "pytest-cov", "pytest-mock (>=3.3) name = "unidecode" version = "1.3.8" description = "ASCII transliterations of Unicode text" -category = "main" optional = false python-versions = ">=3.5" files = [ @@ -7328,7 +7013,6 @@ files = [ name = "uritemplate" version = "4.1.1" description = "Implementation of RFC 6570 URI Templates" -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -7340,7 +7024,6 @@ files = [ name = "urllib3" version = "2.2.1" description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7358,7 +7041,6 @@ zstd = ["zstandard (>=0.18.0)"] name = "uuid" version = "1.30" description = "UUID object and generation functions (Python 2.3 or higher)" -category = "main" optional = false python-versions = "*" files = [ @@ -7369,7 +7051,6 @@ files = [ name = "uuid6" version = "2023.5.2" description = "New time-based UUID formats which are suited for use as a database key" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7381,7 +7062,6 @@ files = [ name = "uvicorn" version = "0.23.2" description = "The lightning-fast ASGI server." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7400,7 +7080,6 @@ standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", name = "vine" version = "5.1.0" description = "Python promises." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -7412,7 +7091,6 @@ files = [ name = "virtualenv" version = "20.25.1" description = "Virtual Python Environment builder" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7433,7 +7111,6 @@ test = ["covdefaults (>=2.3)", "coverage (>=7.2.7)", "coverage-enable-subprocess name = "vtk" version = "9.3.0" description = "VTK is an open-source toolkit for 3D computer graphics, image processing, and visualization" -category = "main" optional = false python-versions = "*" files = [ @@ -7475,7 +7152,6 @@ web = ["wslink (>=1.0.4)"] name = "wand" version = "0.6.13" description = "Ctypes-based simple MagickWand API binding for Python" -category = "main" optional = false python-versions = "*" files = [ @@ -7491,7 +7167,6 @@ test = ["pytest (>=7.2.0)"] name = "watchdog" version = "4.0.0" description = "Filesystem events monitoring" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7533,7 +7208,6 @@ watchmedo = ["PyYAML (>=3.10)"] name = "watchfiles" version = "0.18.1" description = "Simple, modern and high performance file watching and code reload in python." -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7564,7 +7238,6 @@ anyio = ">=3.0.0" name = "wcwidth" version = "0.2.13" description = "Measures the displayed width of unicode strings in a terminal" -category = "main" optional = false python-versions = "*" files = [ @@ -7576,7 +7249,6 @@ files = [ name = "webencodings" version = "0.5.1" description = "Character encoding aliases for legacy web content" -category = "main" optional = false python-versions = "*" files = [ @@ -7588,7 +7260,6 @@ files = [ name = "websockets" version = "12.0" description = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7670,7 +7341,6 @@ files = [ name = "werkzeug" version = "2.3.8" description = "The comprehensive WSGI web application library." -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7689,7 +7359,6 @@ watchdog = ["watchdog (>=2.3)"] name = "whitenoise" version = "6.6.0" description = "Radically simplified static file serving for WSGI applications" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7704,7 +7373,6 @@ brotli = ["Brotli"] name = "win-unicode-console" version = "0.5" description = "Enable Unicode input and display when running Python from Windows console." -category = "main" optional = false python-versions = "*" files = [ @@ -7715,7 +7383,6 @@ files = [ name = "wrapt" version = "1.16.0" description = "Module for decorators, wrappers and monkey patching." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -7795,7 +7462,6 @@ files = [ name = "xlrd" version = "2.0.1" description = "Library for developers to extract data from Microsoft Excel (tm) .xls spreadsheet files" -category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" files = [ @@ -7812,7 +7478,6 @@ test = ["pytest", "pytest-cov"] name = "xlsxwriter" version = "3.2.0" description = "A Python module for creating Excel XLSX files." -category = "main" optional = false python-versions = ">=3.6" files = [ @@ -7824,7 +7489,6 @@ files = [ name = "xvfbwrapper" version = "0.2.9" description = "run headless display inside X virtual framebuffer (Xvfb)" -category = "main" optional = false python-versions = "*" files = [ @@ -7835,7 +7499,6 @@ files = [ name = "yandex-music" version = "2.2.0" description = "Неофициальная Python библиотека для работы с API сервиса Яндекс.Музыка." -category = "main" optional = false python-versions = "~=3.7" files = [ @@ -7851,7 +7514,6 @@ requests = {version = "*", extras = ["socks"]} name = "yarl" version = "1.9.4" description = "Yet another URL library" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -7955,7 +7617,6 @@ multidict = ">=4.0" name = "yt-dlp" version = "2023.12.30" description = "A youtube-dl fork with additional features and patches" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7977,7 +7638,6 @@ websockets = ">=12.0" name = "ytmusicapi" version = "1.5.4" description = "Unofficial API for YouTube Music" -category = "main" optional = false python-versions = ">=3.8" files = [ @@ -7992,7 +7652,6 @@ requests = ">=2.22" name = "zope-interface" version = "6.2" description = "Interfaces for Python" -category = "main" optional = false python-versions = ">=3.7" files = [ @@ -8045,4 +7704,4 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"] [metadata] lock-version = "2.0" python-versions = ">=3.11,<3.13" -content-hash = "70d22cd625166376e0dfc3ceabe0d7067cc69265ebc4731f642fea9ad8582897" +content-hash = "702c5d8af4887ee7868e86472f96f32656a69d46f9305e337c1387a446202944" diff --git a/pyproject.toml b/pyproject.toml index 636e820..fdc1e45 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -27,7 +27,6 @@ django-allauth = "^0.54.0" django-crispy-forms = "^2.1" crispy-bootstrap5 = "^0.7" django-redis = "^5.2.0" -django-ckeditor = "^6.5.1" django-colorfield = "^0.11.0" djangorestframework = "^3.14.0" django-rest-auth = "^0.9.5" @@ -121,6 +120,7 @@ python-levenshtein = "^0.23.0" pylast = "^5.2.0" textract = {git = "https://github.com/Alexander-D-Karpov/textract.git", branch = "master"} librosa = "^0.10.1" +django-ckeditor-5 = "^0.2.12" [build-system]