Compare commits

..

No commits in common. "f3c6f92511575675daec9a358de1630bada98efc" and "517c427023891e8f8ebacdfd5a2d10466155c88b" have entirely different histories.

16 changed files with 42 additions and 470 deletions

3
.gitignore vendored
View File

@ -6,5 +6,4 @@ __pycache__/
identifier.sqlite identifier.sqlite
vk_config.v2.json vk_config.v2.json
crossposting_backend/private/settings.py crossposting_backend/private/settings.py
logs/ logs/
static/

View File

@ -1,3 +0,0 @@
Этот продукт является ОБЩЕСТВЕННЫМ ДОСТОЯНИЕМ и может быть использован КАК ЕСТЬ, со всеми достоинствами и недостатками, полностью или частично, кем угодно и в каких угодно целях БЕЗ КАКИХ-ЛИБО ОГРАНИЧЕНИЙ.
This product is PUBLIC DOMAIN and may be used AS IS, with all advantages and faults, in whole or in part, by anyone for any purpose, WITHOUT ANY CONDITIONS.

BIN
Logo.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

101
Logo.svg
View File

@ -1,101 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="210mm"
height="297mm"
viewBox="0 0 210 297"
version="1.1"
id="svg5"
inkscape:version="1.1.2 (0a00cf5339, 2022-02-04)"
sodipodi:docname="LogoCrossPosting.svg"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:document-units="mm"
showgrid="false"
inkscape:zoom="2"
inkscape:cx="273.25"
inkscape:cy="428.25"
inkscape:window-width="1366"
inkscape:window-height="704"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1" />
<defs
id="defs2" />
<g
inkscape:label="Слой 1"
inkscape:groupmode="layer"
id="layer1">
<circle
id="path13483-1-8-1"
cx="75.798073"
cy="-104.49218"
r="3.5844672"
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="scale(1,-1)" />
<circle
id="path13483-1-8-1-3"
cx="61.192924"
cy="-104.20211"
r="3.5844672"
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="scale(1,-1)" />
<circle
id="path13483-1-8-1-7"
cx="61.699493"
cy="-119.37672"
r="3.5844672"
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
transform="scale(1,-1)" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 64.149924,116.09775 10.033647,-9.60987"
id="path14457-0-6"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 61.183361,107.24427 v 9.32318"
id="path14457-2"
sodipodi:nodetypes="cc" />
<circle
id="path13483-1-8-1-5"
cx="75.844719"
cy="134.38693"
r="3.5844672"
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<circle
id="path13483-1-8-1-3-3"
cx="61.239571"
cy="134.67699"
r="3.5844672"
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 64.196572,122.78136 10.033647,9.60987"
id="path14457-0-6-9"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 61.230009,131.63484 v -9.32318"
id="path14457-2-3"
sodipodi:nodetypes="cc" />
<circle
style="fill:none;stroke:#000000;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path15124"
cx="68.566109"
cy="119.2259"
r="22.978039" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

View File

@ -1,6 +1,6 @@
# Описание # Описание
Приложение для автопостинга содержимого со ссылкой в социальные сети. Приложение для автопостинга содержимого со ссылкой в социальные сети.
Приложение реализовано на Django 4.1. Приложение реализовано на Django 4.1.
На данный момент реализован автопостинг в ВКонтакте, Одноклассники и телеграм. На данный момент реализован автопостинг в ВКонтакте, Одноклассники и телеграм.
Автопостинг на уровне архитектуры реализован с помощью класса "Маркетолог" cms.promoters.Marketer. Автопостинг на уровне архитектуры реализован с помощью класса "Маркетолог" cms.promoters.Marketer.
@ -16,36 +16,30 @@
4. Выбираем тип приложения "Пользовательское". 4. Выбираем тип приложения "Пользовательское".
5. Ставим галочку "Пользовательское" 5. Ставим галочку "Пользовательское"
6. Заполняем описание. 6. Заполняем описание.
7. Нажимаем "Добавить платформу". 7. Нажимаем "Добавить платформу".
8. Выбираем OAuth. 8. Выбираем OAuth.
9. В списке разрешённых redirect_uri указываем URL вашего сайта, откуда будете производить кросспостинг, 9. В списке разрешённых redirect_uri указываем URL вашего сайта, откуда будете производить кросспостинг,
например, https://mirocod.ru например, https://mirocod.ru
10. Ставим галочку "Разрешить клиентскую OAuth авторизацию". 10. Ставим галочку "Разрешить клиентскую OAuth авторизацию".
11. Выставляем права: 11. Выставляем права:
* Доступ к личной информации через OAuth (VALUABLE_ACCESS): Опционально * Доступ к личной информации через OAuth (VALUABLE_ACCESS): Опционально
* Получение длинных токенов OAuth (LONG_ACCESS_TOKEN): Опционально * Получение длинных токенов OAuth (LONG_ACCESS_TOKEN): Опционально
* Установка статуса (SET_STATUS): Не используется * Установка статуса (SET_STATUS): Не используется
* Изменение фотографий и фотоальбомов (PHOTO_CONTENT): Не используется * Изменение фотографий и фотоальбомов (PHOTO_CONTENT): Не используется
* Управление группами (GROUP_CONTENT): Обязательно * Управление группами (GROUP_CONTENT): Обязательно
11. Нажмите "Сохранить". 11. Нажмите "Сохранить".
12. Вам на почту придут ключи. 12. Вам на почту придут ключи.
13. Нажмите на кнопку "Получить новый" рядом с надписью "Вечный access_token". 13. Нажмите на кнопку "Получить новый" рядом с надписью "Вечный access_token".
14. Скопируйте значение "Вечный access_token" в .env-файл в корне вашего приложения, в качестве значения OK_ACCESS_TOKEN: 14. Скопируйте значение "Вечный access_token" в .env-файл в корне вашего приложения, в качестве значения OK_ACCESS_TOKEN:
15. Вставьте их в .env-файл в корне вашего приложения: 15. Вставьте их в .env-файл в корне вашего приложения:
* Публичный ключ приложения - в качестве значения OK_APPLICATION_KEY * Публичный ключ приложения - в качестве значения OK_APPLICATION_KEY
* Секретный ключ приложения - в качестве значения OK_APPLICATION_SECRET_KEY * Секретный ключ приложения - в качестве значения OK_APPLICATION_SECRET_KEY
## Настраиваем доступ к ВКонтакте
1. Создайте приложение в ВК (standalone). Укажите в приложении сообщество ## Настраиваем доступ к ВКонтакте
2. Скопируйте ссылку ниже, укажите ID приложения.Вставьте ссылку в адресную строку браузере, нажмите Enter 1. Укажите логин, ваш email, под которым вы авторизуетесь в ВК, в качестве значения VK_LOGIN
https://oauth.vk.com/authorize?client_id=ID-приложения&scope=wall,offline&redirect_uri=https://oauth.vk.com/blank.html&display=page&response_type=token&revoke=1 2. Укажите пароль, в качестве значения VK_PASSWORD
3. После этого в вашей адресной строке появится необходимый ключ. Он копируется вручную: после access\_token= и перед &expires\_in. 3. Укажите ид группы, добавьте к нему минус в начале. Т.е. если № группы 7002, то нужно указать -7002, в качестве значения VK_OWNER_ID
4. Укажите токен, в качестве значения VK_TOKIN
5. Укажите id сообщества со знаком «-», в качестве значения VK_OWNER_ID
## Настраиваем доступ к телеграм ## Настраиваем доступ к телеграм
@ -56,80 +50,64 @@
5. Добавьте бота в админы группы 5. Добавьте бота в админы группы
6. Добавьте несколько тестовых сообщений в группу 6. Добавьте несколько тестовых сообщений в группу
7. Запустите команду: 7. Запустите команду:
``` ```
python3.8 manage.py get_telegram_group_id python3.8 manage.py get_telegram_group_id
``` ```
6. В результате будет выведен ид канала 6. В результате будет выведен ид канала
7. Вставьте полученный ид в .env-файл, переменная TELEGRAM_CHAT_ID 7. Вставьте полученный ид в .env-файл, переменная TELEGRAM_CHAT_ID
### Возможные ошибки ### Возможные ошибки
7. Если будет ошибка, что "Нет обновлений", значит, нужно прислать больше сообщений в группу и быстрее запустить команду. 7. Если будет ошибка, что "Нет обновлений", значит, нужно прислать больше сообщений в группу и быстрее запустить команду.
Возможно бот успевает прочитать обновления до вас. Возможно бот успевает прочитать обновления до вас.
# Задаём доступ к веб-интерфейсу # Задаём доступ к веб-интерфейсу
1. Зайдите по ssh на хостинг. 1. Зайдите по ssh на хостинг.
2. Зайдите по root. 2. Зайдите по root.
3. Активируйте виртуальное окружение: 3. Активируйте виртуальное окружение:
```shell ```shell
source /home/crossposting_env/bin/activate source /home/crossposting_env/bin/activate
``` ```
4. Перейдите в папку проекта: 4. Перейдите в папку проекта:
```shell ```shell
cd /var/www/crossposting/backend/current/ cd /var/www/crossposting/backend/current/
``` ```
5. Запустите консоль django: 5. Запустите консоль django:
```shell ```shell
python3.8 manage.py shell python3.8 manage.py shell
``` ```
1. Выполните команду на python: 1. Выполните команду на python:
```python ```python
from django.contrib.auth.models import User from django.contrib.auth.models import User
``` ```
2. Создайте пользователя, под которым будете авторизоваться. Укажите своё имя пользователя, электропочту и пароль: 2. Создайте пользователя, под которым будете авторизоваться. Укажите своё имя пользователя, электропочту и пароль:
```python ```python
user = User.objects.create_user(username='user', email='user@mail.pro', password='123123123') user = User.objects.create_user(username='user', email='user@mail.pro', password='123123123')
``` ```
3. Выйти из консоли: 3. Выйти из консоли:
```python ```python
quit() quit()
``` ```
# Шифруем .env-файл # Шифруем .env-файл
1. По умолчанию настройка шифрования в crossposting_backend/private/settings.py ENV_ENCODED равна False. Это означает, 1. По умолчанию настройка шифрования в crossposting_backend/private/settings.py ENV_ENCODED равна False. Это означает,
что .env-файл не шифрован. что .env-файл не шифрован.
2. Если нужно повысить защищённость данных, то шифруем .env-файл. 2. Если нужно повысить защищённость данных, то шифруем .env-файл.
3. Если у вас уже зашифрован .env-файл, то на всякий случай создайте резервную копию этого файла. 3. Если у вас уже зашифрован .env-файл, то на всякий случай создайте резервную копию этого файла.
4. Далее создайте .env-файл и укажите незашифрованные доступы к социальным сетям. 4. Далее создайте .env-файл и укажите незашифрованные доступы к социальным сетям.
5. В crossposting_backend/private/settings.py значение ENV_ENCODED д.б. False. 5. В crossposting_backend/private/settings.py значение ENV_ENCODED д.б. False.
6. Перезапустите веб-приложение: 6. Перезапустите веб-приложение:
```shell ```shell
supervisorctl restart crossposting_django supervisorctl restart crossposting_django
``` ```
7. Выполните команду для шифровки: 7. Выполните команду для шифровки:
python3.8 manage.py encode_file python3.8 manage.py encode_file
8. В результате будет создан файл .env.encoded 8. В результате будет создан файл .env.encoded
9. Замените .env созданным файлом .env.encoded 9. Замените .env созданным файлом .env.encoded
10. В crossposting_backend/private/settings.py значение ENV_ENCODED замените на True. 10. В crossposting_backend/private/settings.py значение ENV_ENCODED замените на True.
11. Перезапустите веб-приложение: 11. Перезапустите веб-приложение:
```shell ```shell
supervisorctl restart crossposting_django supervisorctl restart crossposting_django
``` ```

View File

@ -37,22 +37,21 @@ class TelegramPromoter(Promoter):
class VkontaktePromoter(Promoter): class VkontaktePromoter(Promoter):
def promote(self): def promote(self):
vk_login = promoter_secrets['VK_LOGIN']
vk_password = promoter_secrets['VK_PASSWORD']
vk_owner_id = promoter_secrets['VK_OWNER_ID'] vk_owner_id = promoter_secrets['VK_OWNER_ID']
vk_token = promoter_secrets['VK_TOKEN']
from_group = 1 import vk_api
session = vk_api.VkApi(login=vk_login,
password=vk_password)
session.auth()
api = session.get_api()
try: try:
requests.post('https://api.vk.com/method/wall.post', api.wall.post(owner_id=vk_owner_id,
params={ message=self.article.body,
'access_token': vk_token, attachments=self.article.link)
'owner_id': vk_owner_id, except vk_api.VkApiError as exc:
'from_group': from_group,
'message': self.article.body,
'attachment': self.article.link,
'signed': 0,
'v': '5.131'
})
except Exception as exc:
raise PromoteError(exc) raise PromoteError(exc)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,5 +1,5 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load django_bootstrap5 %} {% load bootstrap5 %}
{% block content %} {% block content %}
<div class="container"> <div class="container">
<div class="row my-5"> <div class="row my-5">
@ -13,7 +13,7 @@
> >
{% csrf_token %} {% csrf_token %}
{% bootstrap_form new_article_form %} {% bootstrap_form new_article_form %}
<div> {% buttons %}
<div class="row"> <div class="row">
<div class="col"> <div class="col">
<button <button
@ -27,7 +27,8 @@
<div id="vkShare" class="col"></div> <div id="vkShare" class="col"></div>
</div> </div>
</div>
{% endbuttons %}
</form> </form>
</div> </div>
</div> </div>
@ -63,4 +64,4 @@
} }
window.addEventListener('DOMContentLoaded', main) window.addEventListener('DOMContentLoaded', main)
</script> </script>
{% endblock %} {% endblock %}

View File

@ -3,12 +3,10 @@
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<title>Продвижение новостей в соц. сетях</title> <title>Продвижение новостей в соц. сетях</title>
{% load django_bootstrap5 %} {% load bootstrap5 %}
{% bootstrap_css %} {% bootstrap_css %}
{% bootstrap_javascript %} {% bootstrap_javascript %}
{% bootstrap_messages %} {% bootstrap_messages %}
{% load static %}
<link rel="icon" href="{% static 'cms/icons/favicon.ico' %}">
<script type="text/javascript" src="https://vk.com/js/api/share.js?93" charset="windows-1251"></script> <script type="text/javascript" src="https://vk.com/js/api/share.js?93" charset="windows-1251"></script>
</head> </head>
<body> <body>
@ -17,4 +15,4 @@
{% block extra_scripts %} {% block extra_scripts %}
{% endblock %} {% endblock %}
</body> </body>
</html> </html>

View File

@ -1,5 +1,5 @@
{% extends 'base.html' %} {% extends 'base.html' %}
{% load django_bootstrap5 %} {% load bootstrap5 %}
{% block content %} {% block content %}
<div class="container"> <div class="container">
<div class="row"> <div class="row">
@ -11,16 +11,16 @@
> >
{% csrf_token %} {% csrf_token %}
{% bootstrap_form user_form %} {% bootstrap_form user_form %}
<div> {% buttons %}
<button <button
class="btn btn-primary" class="btn btn-primary"
type="submit" type="submit"
> >
Войти Войти
</button> </button>
</div> {% endbuttons %}
</form> </form>
</div> </div>
</div> </div>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -8,8 +8,4 @@ server {
location / { location / {
proxy_pass http://localhost:8888; proxy_pass http://localhost:8888;
} }
location /static/ {
alias /var/www/crossposting/backend/current/static/;
expires max;
}
} }

View File

@ -37,12 +37,11 @@ def return_env(env_key: str) -> str:
BASE_DIR = Path(__file__).resolve().parent.parent BASE_DIR = Path(__file__).resolve().parent.parent
env_file = path.join(BASE_DIR, '.env') env_file = path.join(BASE_DIR, '.env')
#dotenv.read_dotenv(env_file) dotenv.read_dotenv(env_file)
dotenv.load_dotenv(env_file)
promoter_env_keys = ( promoter_env_keys = (
'TELEGRAM_BOT_TOKEN', 'TELEGRAM_CHAT_ID', 'JOOMLA_TOKEN', 'TELEGRAM_BOT_TOKEN', 'TELEGRAM_CHAT_ID', 'JOOMLA_TOKEN',
'VK_OWNER_ID', 'VK_TOKEN', 'OK_ACCESS_TOKEN', 'OK_APPLICATION_KEY', 'VK_LOGIN', 'VK_PASSWORD', 'VK_OWNER_ID', 'OK_ACCESS_TOKEN', 'OK_APPLICATION_KEY',
'OK_APPLICATION_SECRET_KEY', 'OK_GROUP_ID', 'OK_APPLICATION_SECRET_KEY', 'OK_GROUP_ID',
) )
promoter_secrets = {} promoter_secrets = {}
@ -72,7 +71,7 @@ INSTALLED_APPS = [
'django.contrib.messages', 'django.contrib.messages',
'django.contrib.staticfiles', 'django.contrib.staticfiles',
'cms', 'cms',
'django_bootstrap5', 'bootstrap5',
] ]
MIDDLEWARE = [ MIDDLEWARE = [
@ -148,7 +147,6 @@ USE_TZ = True
# https://docs.djangoproject.com/en/4.1/howto/static-files/ # https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = 'static/' STATIC_URL = 'static/'
STATIC_ROOT = path.join(BASE_DIR, 'static')
# Default primary key field type # Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field # https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field

273
poetry.lock generated
View File

@ -1,273 +0,0 @@
# This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand.
[[package]]
name = "asgiref"
version = "3.8.1"
description = "ASGI specs, helper code, and adapters"
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47"},
{file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"},
]
[package.extras]
tests = ["mypy (>=0.800)", "pytest", "pytest-asyncio"]
[[package]]
name = "certifi"
version = "2025.1.31"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"},
{file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"},
]
[[package]]
name = "charset-normalizer"
version = "3.4.1"
description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
optional = false
python-versions = ">=3.7"
groups = ["main"]
files = [
{file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"},
{file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"},
{file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"},
{file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"},
{file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"},
{file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"},
{file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"},
{file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"},
{file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"},
{file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"},
{file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"},
{file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"},
{file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"},
{file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"},
{file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"},
{file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"},
{file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"},
{file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"},
{file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"},
{file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"},
{file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"},
{file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"},
{file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"},
{file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"},
{file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"},
{file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"},
{file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"},
{file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"},
{file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"},
{file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"},
{file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"},
{file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"},
{file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"},
{file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"},
{file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"},
{file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"},
{file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"},
{file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"},
{file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"},
{file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"},
{file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"},
{file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"},
{file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"},
{file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"},
{file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"},
{file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"},
{file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"},
{file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"},
{file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"},
{file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"},
{file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"},
{file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"},
{file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"},
{file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"},
{file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"},
{file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"},
{file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"},
{file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"},
{file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"},
{file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"},
{file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"},
{file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"},
{file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"},
{file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"},
{file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"},
{file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"},
{file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"},
{file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"},
{file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"},
{file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"},
{file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"},
{file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"},
{file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"},
{file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"},
{file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"},
{file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"},
{file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"},
{file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"},
{file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"},
{file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"},
{file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"},
]
[[package]]
name = "django"
version = "5.2"
description = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
optional = false
python-versions = ">=3.10"
groups = ["main"]
files = [
{file = "Django-5.2-py3-none-any.whl", hash = "sha256:91ceed4e3a6db5aedced65e3c8f963118ea9ba753fc620831c77074e620e7d83"},
{file = "Django-5.2.tar.gz", hash = "sha256:1a47f7a7a3d43ce64570d350e008d2949abe8c7e21737b351b6a1611277c6d89"},
]
[package.dependencies]
asgiref = ">=3.8.1"
sqlparse = ">=0.3.1"
tzdata = {version = "*", markers = "sys_platform == \"win32\""}
[package.extras]
argon2 = ["argon2-cffi (>=19.1.0)"]
bcrypt = ["bcrypt"]
[[package]]
name = "django-bootstrap5"
version = "25.1"
description = "Bootstrap 5 for Django"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "django_bootstrap5-25.1-py3-none-any.whl", hash = "sha256:964ad2d970d0495b030b86f31b33033dfdfe839a67b32ea599fa02eb39988ae7"},
{file = "django_bootstrap5-25.1.tar.gz", hash = "sha256:e81c77eb710356f94e426a51f4f469890d5720f5e7e53d650f4405d4cc94da04"},
]
[package.dependencies]
django = ">=4.2"
[package.extras]
jinja = ["jinja2 (>=3.0,<4)"]
[[package]]
name = "idna"
version = "3.10"
description = "Internationalized Domain Names in Applications (IDNA)"
optional = false
python-versions = ">=3.6"
groups = ["main"]
files = [
{file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
{file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
]
[package.extras]
all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"]
[[package]]
name = "python-dotenv"
version = "1.1.0"
description = "Read key-value pairs from a .env file and set them as environment variables"
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d"},
{file = "python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5"},
]
[package.extras]
cli = ["click (>=5.0)"]
[[package]]
name = "requests"
version = "2.32.3"
description = "Python HTTP for Humans."
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
{file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
]
[package.dependencies]
certifi = ">=2017.4.17"
charset-normalizer = ">=2,<4"
idna = ">=2.5,<4"
urllib3 = ">=1.21.1,<3"
[package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
name = "sqlparse"
version = "0.5.3"
description = "A non-validating SQL parser."
optional = false
python-versions = ">=3.8"
groups = ["main"]
files = [
{file = "sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca"},
{file = "sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272"},
]
[package.extras]
dev = ["build", "hatch"]
doc = ["sphinx"]
[[package]]
name = "tzdata"
version = "2025.2"
description = "Provider of IANA time zone data"
optional = false
python-versions = ">=2"
groups = ["main"]
markers = "sys_platform == \"win32\""
files = [
{file = "tzdata-2025.2-py2.py3-none-any.whl", hash = "sha256:1a403fada01ff9221ca8044d701868fa132215d84beb92242d9acd2147f667a8"},
{file = "tzdata-2025.2.tar.gz", hash = "sha256:b60a638fcc0daffadf82fe0f57e53d06bdec2f36c4df66280ae79bce6bd6f2b9"},
]
[[package]]
name = "urllib3"
version = "2.4.0"
description = "HTTP library with thread-safe connection pooling, file post, and more."
optional = false
python-versions = ">=3.9"
groups = ["main"]
files = [
{file = "urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813"},
{file = "urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466"},
]
[package.extras]
brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""]
h2 = ["h2 (>=4,<5)"]
socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"]
zstd = ["zstandard (>=0.18.0)"]
[metadata]
lock-version = "2.1"
python-versions = ">=3.13"
content-hash = "81c6b172888a92c71efbde5d92319e5ca39f5125e57387ef582cacda2be0826f"

View File

@ -1,20 +0,0 @@
[project]
name = "cross-posting"
version = "0.1.0"
description = ""
authors = [
{name = "bvn13",email = "from.github@bvn13.me"}
]
readme = "README.md"
requires-python = ">=3.13"
dependencies = [
"django (>=5.2,<6.0)",
"python-dotenv (>=1.1.0,<2.0.0)",
"django-bootstrap5 (>=25.1,<26.0)",
"requests (>=2.32.3,<3.0.0)"
]
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"