Merge pull request 'Oauth Anthentication' (#48) from v2 into master
continuous-integration/drone/push Build is passing Details
continuous-integration/drone/tag Build is passing Details

Reviewed-on: #48
This commit is contained in:
Michel Roux 2022-09-12 18:47:36 +00:00
commit 8f507b0fcd
7 changed files with 353 additions and 132 deletions

View File

@ -1 +1,3 @@
DISCORD_TOKEN= DISCORD_TOKEN=
OAUTH2_CLIENT_ID=
OAUTH2_CLIENT_SECRET=

View File

@ -13,21 +13,37 @@ Simple website that guides you to invite a bot to read and format scheduled even
- Go to the [Discord Developer Portal](https://discord.com/developers/applications) and create a new application. - Go to the [Discord Developer Portal](https://discord.com/developers/applications) and create a new application.
- Enable the `Build-A-Bot` option in the `Bot` panel. - Enable the `Build-A-Bot` option in the `Bot` panel.
- Click on `Reset Token` and keep it in a safe place, you will need it. - Click on `Reset Token` and keep it in a safe place, you will need it.
- Click on `Reset Secret` in the `OAuth2` panel, copy both `Client ID` and `Client Secret` and keep it in a safe place, you will need it.
- Configure the rest of your app and bot as you like (name, icon, username, etc.) - Configure the rest of your app and bot as you like (name, icon, username, etc.)
### 2) With Docker ### 2) With Docker
- Install [Docker](https://docs.docker.com/get-docker/) - Install [Docker](https://docs.docker.com/get-docker/)
- Run `docker run -p 5000 -e DISCORD_TOKEN=your_bot_token xefir/divent` - Run
- The app is accessible at http://localhost:5000 ```bash
docker run -p 5000 \
-e DISCORD_TOKEN=your_bot_token \
-e OAUTH2_CLIENT_ID=your_client_id \
-e OAUTH2_CLIENT_SECRET=your_client_secret \
xefir/divent
```
### 2) Without Docker ### 2) Without Docker
- Install [Python 3](https://www.python.org/downloads/) - Install [Python 3](https://www.python.org/downloads/)
- Install [Pip](https://pip.pypa.io/en/stable/installing/) - Install [Pip](https://pip.pypa.io/en/stable/installing/)
- Run `pip install divent` - Run `pip install divent`
- Run `DISCORD_TOKEN=your_bot_token divent` - Run
- The app is accessible at http://localhost:5000 ```bash
DISCORD_TOKEN=your_bot_token \
OAUTH2_CLIENT_ID=your_client_id \
OAUTH2_CLIENT_SECRET=your_client_secret \
divent
```
### 3) Open your browser
The app is accessible at http://localhost:5000
## Links ## Links

View File

@ -1,25 +1,34 @@
import json import json
import logging import logging
from datetime import datetime, timedelta from datetime import datetime, timedelta
from functools import wraps
from os import environ, path from os import environ, path
from typing import Optional from typing import Dict, Optional
from disnake import Client, Guild from disnake import Client, Guild
from dotenv import load_dotenv from dotenv import load_dotenv
from ics import Calendar, ContentLine, Event from ics import Calendar, ContentLine, Event
from ics.alarm import DisplayAlarm from ics.alarm import DisplayAlarm
from quart import Quart, redirect, render_template, request, url_for from quart import Quart, redirect, render_template, request, session, url_for
from requests_oauthlib import OAuth2Session # type: ignore
import sentry_sdk import sentry_sdk
from sentry_sdk.integrations.quart import QuartIntegration from sentry_sdk.integrations.quart import QuartIntegration
from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware # type: ignore from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware # type: ignore
load_dotenv() load_dotenv()
QUART_DEBUG = environ.get("QUART_DEBUG", False)
DISCORD_TOKEN = environ.get("DISCORD_TOKEN") DISCORD_TOKEN = environ.get("DISCORD_TOKEN")
OAUTH2_CLIENT_ID = environ.get("OAUTH2_CLIENT_ID")
OAUTH2_CLIENT_SECRET = environ.get("OAUTH2_CLIENT_SECRET")
if not DISCORD_TOKEN: if not DISCORD_TOKEN:
raise Exception("Missing DISCORD_TOKEN") raise Exception("Missing DISCORD_TOKEN")
if not OAUTH2_CLIENT_ID:
raise Exception("Missing OAUTH2_CLIENT_ID")
if not OAUTH2_CLIENT_SECRET:
raise Exception("Missing OAUTH2_CLIENT_SECRET")
QUART_DEBUG = environ.get("QUART_DEBUG", False)
if QUART_DEBUG: if QUART_DEBUG:
logging.basicConfig(level=logging.DEBUG) logging.basicConfig(level=logging.DEBUG)
@ -27,6 +36,10 @@ SENTRY_DSN = environ.get("SENTRY_DSN")
if SENTRY_DSN: if SENTRY_DSN:
sentry_sdk.init(SENTRY_DSN, integrations=[QuartIntegration()]) sentry_sdk.init(SENTRY_DSN, integrations=[QuartIntegration()])
API_BASE_URL = environ.get("API_BASE_URL", "https://discordapp.com/api")
AUTHORIZATION_BASE_URL = f"{API_BASE_URL}/oauth2/authorize"
TOKEN_URL = f"{API_BASE_URL}/oauth2/token"
class Discord(Client): class Discord(Client):
async def on_ready(self): async def on_ready(self):
@ -35,6 +48,7 @@ class Discord(Client):
client = Discord() client = Discord()
app = Quart(__name__) app = Quart(__name__)
app.config["SECRET_KEY"] = OAUTH2_CLIENT_SECRET
app.asgi_app = ProxyHeadersMiddleware(app.asgi_app, "*") # type: ignore app.asgi_app = ProxyHeadersMiddleware(app.asgi_app, "*") # type: ignore
@ -60,6 +74,28 @@ async def not_found(error: Exception):
return await render_template("error.html.j2", error=str(error)), 404 return await render_template("error.html.j2", error=str(error)), 404
def token_updater(token: str):
session["oauth2_token"] = token
def make_session(
token: Optional[Dict[str, str]] = None, state: Optional[str] = None
) -> OAuth2Session:
return OAuth2Session(
client_id=OAUTH2_CLIENT_ID,
token=token,
state=state,
scope=["identify", "guilds"],
redirect_uri=f"{request.host_url}callback",
auto_refresh_kwargs={
"client_id": OAUTH2_CLIENT_ID,
"client_secret": OAUTH2_CLIENT_SECRET,
},
auto_refresh_url=TOKEN_URL,
token_updater=token_updater,
)
def i18n(str: str) -> str: def i18n(str: str) -> str:
lang = request.accept_languages.best_match(["en", "fr"]) lang = request.accept_languages.best_match(["en", "fr"])
@ -84,27 +120,98 @@ def days_before_failure() -> int:
return nextDelta.days return nextDelta.days
def cdn_avatar_url(user_id: int, hash: str) -> str:
ext = "gif" if hash.startswith("a_") else "png"
return f"https://cdn.discordapp.com/avatars/{user_id}/{hash}.{ext}"
@app.context_processor @app.context_processor
def context_processor(): def context_processor():
return dict(_=i18n, client=client, days_before_failure=days_before_failure()) return dict(
_=i18n,
client=client,
cdn_avatar_url=cdn_avatar_url,
days_before_failure=days_before_failure(),
)
def login_required(fn):
@wraps(fn)
async def wrapper(*args, **kwargs):
discord = make_session(token=session.get("oauth2_token"))
if discord:
return await fn(*args, **kwargs)
return redirect(url_for(".login"))
return wrapper
@app.route("/") @app.route("/")
async def index(): async def index():
guild_id = request.args.get("guild")
guild = get_guild_by_id(guild_id)
if guild:
return redirect(url_for(".subscribe", guild_id=guild_id))
return await render_template("index.html.j2") return await render_template("index.html.j2")
@app.route("/login")
async def login():
discord = make_session()
authorization_url, state = discord.authorization_url(AUTHORIZATION_BASE_URL)
session["oauth2_state"] = state
return redirect(authorization_url)
@app.route("/callback")
async def callback():
request_values = await request.values
if request_values.get("error"):
return errorhandler(request_values.get("error"))
discord = make_session(state=session.get("oauth2_state"))
token = discord.fetch_token(
TOKEN_URL,
client_secret=OAUTH2_CLIENT_SECRET,
authorization_response=request.url,
)
token_updater(token)
return redirect(url_for(".guilds"))
@app.route("/guilds")
@login_required
async def guilds():
guild = get_guild_by_id(request.args.get("guild"))
if guild:
return redirect(
url_for(".subscribe", guild_id=guild.vanity_url_code or guild.id)
)
discord = make_session(token=session.get("oauth2_token"))
user = discord.get(f"{API_BASE_URL}/users/@me").json()
user_guilds = discord.get(f"{API_BASE_URL}/users/@me/guilds").json()
common_guilds = []
for bot_guild in client.guilds:
for user_guild in user_guilds:
if str(bot_guild.id) == user_guild["id"]:
common_guilds.append(bot_guild)
return await render_template(
"guilds.html.j2", user=user, common_guilds=common_guilds
)
@app.route("/subscribe/<guild_id>") @app.route("/subscribe/<guild_id>")
@login_required
async def subscribe(guild_id: str): async def subscribe(guild_id: str):
guild = get_guild_by_id(guild_id) guild = get_guild_by_id(guild_id)
if guild is None: if guild is None:
return redirect(url_for(".index")) return redirect(url_for(".login"))
discord = make_session(token=session.get("oauth2_token"))
user_guilds = discord.get(f"{API_BASE_URL}/users/@me/guilds").json()
if not any(str(guild.id) == user_guild["id"] for user_guild in user_guilds):
return redirect(url_for(".login"))
return await render_template("subscribe.html.j2", guild=guild) return await render_template("subscribe.html.j2", guild=guild)
@ -113,7 +220,7 @@ async def subscribe(guild_id: str):
async def ical(guild_id: str): async def ical(guild_id: str):
guild = get_guild_by_id(guild_id) guild = get_guild_by_id(guild_id)
if guild is None: if guild is None:
return redirect(url_for(".index")) return redirect(url_for(".login"))
calendar = Calendar() calendar = Calendar()

View File

@ -0,0 +1,55 @@
{% extends "base.html.j2" %}
{% block content %}
<form action="{{ url_for(".guilds") }}" method="get">
<div id="box">
<div id="avatars">
<img src="{{ client.user.display_avatar }}"
alt="{{ _('Bot Logo') }}"
width="80"
height="80"/>
<span id="dots">…</span>
<img src="{{ cdn_avatar_url(user.id, user.avatar) }}"
alt="{{ _('User Avatar') }}"
width="80"
height="80"/>
</div>
<h1>
<a href="{{ url_for(".index") }}">{{ client.user.display_name }}</a>
</h1>
<h3>{{ _('Choose a server:') }}</h3>
<select name="guild" class="black_input">
<option>
&nbsp;
</option>
{% for guild in common_guilds %}
<option value="{{ guild.vanity_url_code|default(guild.id, True) }}">
{{ guild.name }}
</option>
{% endfor %}
</select>
<div class="hr-sect">{{ _("OR") }}</div>
<a class="button"
target="_blank"
href="https://discord.com/api/oauth2/authorize?client_id={{ client.user.id }}&permissions=8589934592&scope=bot">
{{ _("Add the bot on your server") }}
</a>
<ul>
<li>
{{ _("You must have") }}
<strong>{{ _("Manage Server") }}</strong>
{{ _("permission on this server to perform this action") }}
</li>
<li>
{{ _("After adding the bot,") }}
<a href="{{ url_for(".guilds") }}">
<i class="fa fa-refresh"></i>
<strong>{{ _("reload the page") }}</strong>
</a>
</li>
</ul>
</div>
<div id="buttons">
<input type="submit" class="button" value="{{ _("Let's go!") }}"/>
</div>
</form>
{% endblock content %}

View File

@ -24,41 +24,9 @@
{{ _('Throwing you to a new isekai world') }} {{ _('Throwing you to a new isekai world') }}
</li> </li>
</ul> </ul>
<hr />
<h3>{{ _('Choose a server:') }}</h3>
<select name="guild" class="black_input">
<option>
&nbsp;
</option>
{% for guild in client.guilds %}
<option value="{{ guild.vanity_url_code|default(guild.id, True) }}">
{{ guild.name }}
</option>
{% endfor %}
</select>
<div class="hr-sect">{{ _("OR") }}</div>
<a class="button"
target="_blank"
href="https://discord.com/api/oauth2/authorize?client_id={{ client.user.id }}&permissions=8589934592&scope=bot">
{{ _("Add the bot on your server") }}
</a>
<ul>
<li>
{{ _("You must have") }}
<strong>{{ _("Manage Server") }}</strong>
{{ _("permission on this server to perform this action") }}
</li>
<li>
{{ _("After adding the bot,") }}
<a href="{{ url_for(".index") }}">
<i class="fa fa-refresh"></i>
<strong>{{ _("reload the page") }}</strong>
</a>
</li>
</ul>
</div> </div>
<div id="buttons"> <div id="buttons">
<input type="submit" class="button" value="{{ _("Let's go!") }}"/> <a class="button" href="{{ url_for(".login") }}">{{ _("Let's go!") }}</a>
</div> </div>
</form> </form>
{% endblock content %} {% endblock content %}

230
poetry.lock generated
View File

@ -91,7 +91,7 @@ python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
[[package]] [[package]]
name = "certifi" name = "certifi"
version = "2022.6.15" version = "2022.6.15.1"
description = "Python package for providing Mozilla's CA Bundle." description = "Python package for providing Mozilla's CA Bundle."
category = "main" category = "main"
optional = false optional = false
@ -458,6 +458,19 @@ category = "dev"
optional = false optional = false
python-versions = "*" python-versions = "*"
[[package]]
name = "oauthlib"
version = "3.2.1"
description = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic"
category = "main"
optional = false
python-versions = ">=3.6"
[package.extras]
rsa = ["cryptography (>=3.0.0)"]
signals = ["blinker (>=1.4.0)"]
signedtoken = ["cryptography (>=3.0.0)", "pyjwt (>=2.0.0,<3)"]
[[package]] [[package]]
name = "pathspec" name = "pathspec"
version = "0.10.1" version = "0.10.1"
@ -557,12 +570,45 @@ dotenv = ["python-dotenv"]
[[package]] [[package]]
name = "regex" name = "regex"
version = "2022.8.17" version = "2022.9.11"
description = "Alternative regular expression module, to replace re." description = "Alternative regular expression module, to replace re."
category = "dev" category = "dev"
optional = false optional = false
python-versions = ">=3.6" python-versions = ">=3.6"
[[package]]
name = "requests"
version = "2.28.1"
description = "Python HTTP for Humans."
category = "main"
optional = false
python-versions = ">=3.7, <4"
[package.dependencies]
certifi = ">=2017.4.17"
charset-normalizer = ">=2,<3"
idna = ">=2.5,<4"
urllib3 = ">=1.21.1,<1.27"
[package.extras]
socks = ["PySocks (>=1.5.6,!=1.5.7)"]
use_chardet_on_py3 = ["chardet (>=3.0.2,<6)"]
[[package]]
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.*"
[package.dependencies]
oauthlib = ">=3.0.0"
requests = ">=2.0.0"
[package.extras]
rsa = ["oauthlib[signedtoken] (>=3.0.0)"]
[[package]] [[package]]
name = "sentry-sdk" name = "sentry-sdk"
version = "1.9.8" version = "1.9.8"
@ -735,7 +781,7 @@ testing = ["func-timeout", "jaraco.itertools", "pytest (>=6)", "pytest-black (>=
[metadata] [metadata]
lock-version = "1.1" lock-version = "1.1"
python-versions = "^3.8" python-versions = "^3.8"
content-hash = "b131f13c9fa60df1f080215ed7c899de6f236de569133ee715e0ba1f8ff3c672" content-hash = "8592d4e149ffb70ffc9edc5be4d5be5f2183e4af97ae540394ea784e46d3f2f3"
[metadata.files] [metadata.files]
aiofiles = [ aiofiles = [
@ -858,8 +904,8 @@ blinker = [
{file = "blinker-1.5.tar.gz", hash = "sha256:923e5e2f69c155f2cc42dafbbd70e16e3fde24d2d4aa2ab72fbe386238892462"}, {file = "blinker-1.5.tar.gz", hash = "sha256:923e5e2f69c155f2cc42dafbbd70e16e3fde24d2d4aa2ab72fbe386238892462"},
] ]
certifi = [ certifi = [
{file = "certifi-2022.6.15-py3-none-any.whl", hash = "sha256:fe86415d55e84719d75f8b69414f6438ac3547d2078ab91b67e779ef69378412"}, {file = "certifi-2022.6.15.1-py3-none-any.whl", hash = "sha256:43dadad18a7f168740e66944e4fa82c6611848ff9056ad910f8f7a3e46ab89e0"},
{file = "certifi-2022.6.15.tar.gz", hash = "sha256:84c85a9078b11105f04f3036a9482ae10e4621616db313fe045dd24743a0820d"}, {file = "certifi-2022.6.15.1.tar.gz", hash = "sha256:cffdcd380919da6137f76633531a5817e3a9f268575c128249fb637e4f9e73fb"},
] ]
charset-normalizer = [ charset-normalizer = [
{file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"}, {file = "charset-normalizer-2.1.1.tar.gz", hash = "sha256:5a3d016c7c547f69d6f81fb0db9449ce888b418b5b9952cc5e6e66843e9dd845"},
@ -1156,6 +1202,10 @@ mypy-extensions = [
{file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"},
{file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"},
] ]
oauthlib = [
{file = "oauthlib-3.2.1-py3-none-any.whl", hash = "sha256:88e912ca1ad915e1dcc1c06fc9259d19de8deacd6fd17cc2df266decc2e49066"},
{file = "oauthlib-3.2.1.tar.gz", hash = "sha256:1565237372795bf6ee3e5aba5e2a85bd5a65d0e2aa5c628b9a97b7d7a0da3721"},
]
pathspec = [ pathspec = [
{file = "pathspec-0.10.1-py3-none-any.whl", hash = "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93"}, {file = "pathspec-0.10.1-py3-none-any.whl", hash = "sha256:46846318467efc4556ccfd27816e004270a9eeeeb4d062ce5e6fc7a87c573f93"},
{file = "pathspec-0.10.1.tar.gz", hash = "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"}, {file = "pathspec-0.10.1.tar.gz", hash = "sha256:7ace6161b621d31e7902eb6b5ae148d12cfd23f4a249b9ffb6b9fee12084323d"},
@ -1224,80 +1274,102 @@ quart = [
{file = "Quart-0.18.0.tar.gz", hash = "sha256:0c2465ef5768890431650636f51fe2cc459de6cf4cf3363870ae2a1f3dba9eb1"}, {file = "Quart-0.18.0.tar.gz", hash = "sha256:0c2465ef5768890431650636f51fe2cc459de6cf4cf3363870ae2a1f3dba9eb1"},
] ]
regex = [ regex = [
{file = "regex-2022.8.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:840063aa8eeb1dda07d7d7dee15648838bffef1d415f5f79061854a182a429aa"}, {file = "regex-2022.9.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e41d336e39e9d8e9d1d448a3ea86a2753fd97c83c7b2cc5abb0fc97f383d2108"},
{file = "regex-2022.8.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1df31eaf147ecff3665ba861acb8f78221cd5501df072c9151dfa341dd24599f"}, {file = "regex-2022.9.11-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6c46aa8d54a849aaf5faf69040976c059c325dbc1d927644904ff04f6f10fc55"},
{file = "regex-2022.8.17-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:085ca3dc9360c0210e0a70e5d34d66454a06077644e7679fef6358b1f053e62e"}, {file = "regex-2022.9.11-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e1edba9bd3900f6434f563227ecb8dc4ebb2ca8e39106c0d48a1195a88a3415"},
{file = "regex-2022.8.17-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:21b6f939916aa61beea56393ebc8a9999060632ac22b8193c2cb67d6fd7cb2c3"}, {file = "regex-2022.9.11-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2e4981f41cd1f0fa4632d04b3f2e31502ca85df0b588b22a9f20162611d6c61"},
{file = "regex-2022.8.17-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0a9d5a64e974bc5f160f30f76aaf993d49eeddb405676be6bf76a5a2c131e185"}, {file = "regex-2022.9.11-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1f45b7e96ecdfc36023e33d680af2f5033a418c9ef36efba03f324fc4d9b4f4c"},
{file = "regex-2022.8.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d13bd83284b46c304eb10de93f8a3f2c80361f91f4e8a4e1273caf83e16c4409"}, {file = "regex-2022.9.11-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7c05621e74e40c7ce66080e238ed7f9c23ea049ac7b3cb56360b5a34d407f15"},
{file = "regex-2022.8.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7a52d547259495a53e61e37ffc6d5cecf8d298aeb1bc0d9b25289d65ddb31183"}, {file = "regex-2022.9.11-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2057e34d7af62c8bae1f6bfae585eba9d64ba0c95a5462380e16d842118da7c9"},
{file = "regex-2022.8.17-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:be6f5b453f7ed2219a9555bb6840663950b9ab1dc034216f68eac64db66633c2"}, {file = "regex-2022.9.11-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:28f21c16d624c3b2661c84a6bc68e0fa399fd352f858a092315fe40cd2e20b95"},
{file = "regex-2022.8.17-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:a1e283ad918df44bad3ccf042c2fe283c63d17617570eb91b8c370ef677b0b83"}, {file = "regex-2022.9.11-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:1dde2c60cd015afb04314e55b4270e763aa401099819e80ae41d79886d4ca47e"},
{file = "regex-2022.8.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:5d541bc430a74c787684d1ebcd205a5212a88c3de73848143e77489b2c25b911"}, {file = "regex-2022.9.11-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7df5518b2a92b0205e2bc52d954a74913e11263378db37265f220117092093eb"},
{file = "regex-2022.8.17-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:c78c72f7878071a78337510ec78ab856d60b4bdcd3a95fd68b939e7cb30434b3"}, {file = "regex-2022.9.11-cp310-cp310-musllinux_1_1_ppc64le.whl", hash = "sha256:75280dd3ba402c565d0dfafd712f3c5ffd5b304ae488ecb09ee82732d5496bf6"},
{file = "regex-2022.8.17-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:6b30c8d299ba48ee919064628fd8bc296bdc6e4827d315491bea39437130d3e1"}, {file = "regex-2022.9.11-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:5f1b30c151af4b1f5b8cffff0537377fe4d544e53b4932933fb00714d6bf40d6"},
{file = "regex-2022.8.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:02b6dc102123f5178796dcdb5a90f6e88895607fd1a1d115d8de1af8161ca2b4"}, {file = "regex-2022.9.11-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:5b1b239b7b441f89edca8eeb75c334a4d47e1a4382c1c655f14802604e328a7f"},
{file = "regex-2022.8.17-cp310-cp310-win32.whl", hash = "sha256:5f14430535645712f546f1e07013507d1cc0c8abd851811dacce8c7fb584bf52"}, {file = "regex-2022.9.11-cp310-cp310-win32.whl", hash = "sha256:64ebceb1012dbb2f9bb02a5ad51740f87666d627c6f302c4159c046fdb31a248"},
{file = "regex-2022.8.17-cp310-cp310-win_amd64.whl", hash = "sha256:c4f6609f6e867a58cdf173e1cbe1f3736d25962108bd5cb01ad5a130875ff2c8"}, {file = "regex-2022.9.11-cp310-cp310-win_amd64.whl", hash = "sha256:043625b6115e290c12d736ab9872fd9fe0ac3cf43779411e9ade5496f60f1352"},
{file = "regex-2022.8.17-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4dad9d68574e93e1e23be53b4ecfb0f083bd5cc08cc7f1984a4ee3ebf12aa446"}, {file = "regex-2022.9.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0f37a2c670856e4530b820accacb3ea6e4ab9bb1c7e3c59153cb96b6cd204ad5"},
{file = "regex-2022.8.17-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62d56a9d3c1e5a83076db4da060dad7ea35ac2f3cbd3c53ba5a51fe0caedb500"}, {file = "regex-2022.9.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1c71e74a0174a742b14e7ca30e28c69a3bf895e7f92aaac1cb5bd84f231565d6"},
{file = "regex-2022.8.17-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:61f6966371fa1cbf26c6209771a02bef80336cdaca0c0af4dfa33d51019c0b93"}, {file = "regex-2022.9.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b694a7569842869574320484c0463e75f94abe991e6a448616647fa18c1b78c8"},
{file = "regex-2022.8.17-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c76dd2c0615a28de21c97f9f6862e84faef58ff4d700196b4e395ef6a52291e4"}, {file = "regex-2022.9.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4704278136c6b86aef89adfe8878a72cfc20436d2a5c03bab141cd135a47c0a5"},
{file = "regex-2022.8.17-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:370b1d7aed26e29915c3fb3e72e327f194824a76cedb60c0b9f6c6af53e89d72"}, {file = "regex-2022.9.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8cbe69dd5c4ee69935914b6052b09c70a387300c178b0b3ea1893f85010cabea"},
{file = "regex-2022.8.17-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:634f090a388351eadf1dcc1d168a190718fb68efb4b8fdc1b119cf837ca01905"}, {file = "regex-2022.9.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12655ea0f3bac970bc0421ef6504a585eab6238dee988921395ea1c6fe19a792"},
{file = "regex-2022.8.17-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:79f34d5833cd0d53ecf48bc030e4da3216bd4846224d17eeb64509be5cb098fd"}, {file = "regex-2022.9.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b5498add367e83d0f6bae32e9574cfeb2e3c95defb8dd446bf6b564171cdce7a"},
{file = "regex-2022.8.17-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:b7ddecc80e87acf12c2cf12bf3721def47188c403f04e706f104b5e71fed2f31"}, {file = "regex-2022.9.11-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:84d1776b3c0bb4ecd5c2a6d37dc271f922752e80476aded3b6f2376bc5ab1ede"},
{file = "regex-2022.8.17-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:6f62c8a59f6b8e608880c61b138ae22668184bc266b025d33200dcf2cebe0872"}, {file = "regex-2022.9.11-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:0ec603781007ae2506dba040fe9e770f2b2ae00d8b55793f56392fe6cf5a2b72"},
{file = "regex-2022.8.17-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:95fb62a3980cf43e76c2fe95edab06ec70dc495b8aa660975eb9f0b2ffdae1e1"}, {file = "regex-2022.9.11-cp311-cp311-musllinux_1_1_ppc64le.whl", hash = "sha256:65322a8fba16461eed85aa5ea10e062d72f31da2e49538c650f07675212ae1f1"},
{file = "regex-2022.8.17-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:0de0ce11c0835e1117eacbfe8fa6fa98dc0e8e746b486735cb0fdebe46a02222"}, {file = "regex-2022.9.11-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:c267106b630a81d4f13e94ac206cedfcc0496be51c5158077466dafb5def80f0"},
{file = "regex-2022.8.17-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:abe1adb32e2535aaa171e8b2b2d3f083f863c9974a3e6e7dae6bf4827fc8b983"}, {file = "regex-2022.9.11-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fe614fafdc09e3f58dfeb29534b63a17198a92e6b371a10818ace7044a8a94f0"},
{file = "regex-2022.8.17-cp36-cp36m-win32.whl", hash = "sha256:6059ae91667932d256d9dc03abd3512ebcade322b3a42d1b8354bd1db7f66dcc"}, {file = "regex-2022.9.11-cp311-cp311-win32.whl", hash = "sha256:9e2193eca5c588ca7565760f07d82bbc450dcab54294d8aa0b796ee8521f8485"},
{file = "regex-2022.8.17-cp36-cp36m-win_amd64.whl", hash = "sha256:6af38997f178889d417851bae8fb5c00448f7405cfcab38734d771f1dd5d5973"}, {file = "regex-2022.9.11-cp311-cp311-win_amd64.whl", hash = "sha256:b8472d4239378f8a2e71a9f09f0ebc3b6eccf0a59b31ab91455c169b7784d41c"},
{file = "regex-2022.8.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:cfa62063c5eafb04e4435459ce15746b4ae6c14efeae8f16bd0e3d2895dad698"}, {file = "regex-2022.9.11-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:6db6795c4d1b596a862011949a6a6ea3824dfcff6cb4273f75a2f2ffdfffd4bb"},
{file = "regex-2022.8.17-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:64ecfcc386420192fbe98fdde777d993f7f2dfec9552e4f4024d3447d3a3e637"}, {file = "regex-2022.9.11-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:612782329e9b9063f81365a26731efa4cf550afc8b0b2ae92d41df5c8fbc3acb"},
{file = "regex-2022.8.17-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5910bb355f9517309f77101238dbacb7151ede3434a2f1fad26ecc62f13d8324"}, {file = "regex-2022.9.11-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a15dde0bec401c7831782171d374f87f55600cdc5790611b947beea54d32dbf7"},
{file = "regex-2022.8.17-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae85112da2d826b65aa7c7369c56ca41d9a89644312172979cbee5cf788e0b09"}, {file = "regex-2022.9.11-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:41af38280a9a633f30e284db648ae827327e8d2790e47dc1885780e4d08d35bf"},
{file = "regex-2022.8.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f0c8807bac16984901c0573725bad786f2f004f9bd5df8476c6431097b6c5b3"}, {file = "regex-2022.9.11-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:161963b448c7dfdb2dd78c87e2c7882a536583d46e9ab4b7fb350f5196283720"},
{file = "regex-2022.8.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53c9eca0d6070a8a3de42182ad26daf90ba12132eb74a2f45702332762aff84e"}, {file = "regex-2022.9.11-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e2bb2341f5bc4ee42ee217d041f2f3af32b6d7031de60ea338274123914990f3"},
{file = "regex-2022.8.17-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e37886929ee83a5fa5c73164abada00e7f3cc1cbf3f8f6e1e8cfecae9d6cfc47"}, {file = "regex-2022.9.11-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:985ebdb2ede7f885ceea10d3f418847f31cfaad439d1c6fa9b6b7aa4606a1675"},
{file = "regex-2022.8.17-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:b3379a83dc63fe06538c751961f9ed730b5d7f08f96a57bbad8d52db5820df1f"}, {file = "regex-2022.9.11-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:40ca0f1294e7fdb16c386f532c13342d181084e986572c7bcf256cfe517d6529"},
{file = "regex-2022.8.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:3d3d769b3d485b28d6a591b46723dbacc696e6503f48a3ef52e6fc2c90edb482"}, {file = "regex-2022.9.11-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:a68890ca4931eacc4149bcb5de8b2411c7cf8781d68373789cab48730fc50463"},
{file = "regex-2022.8.17-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:fafed60103132e74cdfbd651abe94801eb87a9765ce275b3dca9af8f3e06622a"}, {file = "regex-2022.9.11-cp36-cp36m-musllinux_1_1_ppc64le.whl", hash = "sha256:1210923af1a9152400308abb0156a3c9a2e4a3a3a9ab0aa2f1713a9859a3809b"},
{file = "regex-2022.8.17-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:14750172c0a616140a8f496dfef28ed24080e87d06d5838e008f959ad307a8c5"}, {file = "regex-2022.9.11-cp36-cp36m-musllinux_1_1_s390x.whl", hash = "sha256:682956726baaf73d8b5275289d1293f8fc2bc32433d0c211326b51c9e792ccc6"},
{file = "regex-2022.8.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:3aafbbf5076f2a48bcf31ceb42b410323daaa0ddb42544640592957bc906ace6"}, {file = "regex-2022.9.11-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:92f9ef720dafe3b76a43f683f9455f5eb2d4dda8a595bc9cacf5741273facff5"},
{file = "regex-2022.8.17-cp37-cp37m-win32.whl", hash = "sha256:74d4aabd612d32282f3cb3ebb4436046fb840d25c754157a755bc9f66e7cd307"}, {file = "regex-2022.9.11-cp36-cp36m-win32.whl", hash = "sha256:c6202fb9c2a1619bde05d742aa2abc2ccfa26ac9be895954172b588560b83c22"},
{file = "regex-2022.8.17-cp37-cp37m-win_amd64.whl", hash = "sha256:4bd9443f7ff6e6288dd4496215c5d903f851e55cbc09d5963587af0c6d565a0a"}, {file = "regex-2022.9.11-cp36-cp36m-win_amd64.whl", hash = "sha256:9b646d2664342270d8cd4828a939675eaf62ad4c3df0633d0bd08d1df3715c2a"},
{file = "regex-2022.8.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b3c7c6c4aac19b964c1d12784aecae7f0315314640b0f41dd6f0d4e2bf439072"}, {file = "regex-2022.9.11-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:66de863f6fb5940b8eaa07ae2c5aa131bdff2f52aaa1d8ef960c44c164c00398"},
{file = "regex-2022.8.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bbaf6785d3f1cd3e617b9d0fb3c5528023ef7bc7cc1356234801dc1941df8ce9"}, {file = "regex-2022.9.11-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0f79ebe9a055359410d33090195ea8a3869c591c6cedb125741c0a05f372d85c"},
{file = "regex-2022.8.17-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d83fd6dd4263595d0e4f595d4abd54397cbed52c0147f7dd148a7b72910301e"}, {file = "regex-2022.9.11-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:da1af5315a070e6abfb2db8b616c1771479f35dca935acadd741cbde5b6ca7f5"},
{file = "regex-2022.8.17-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1b6d2c579ffdcbb3d93f63b6a7f697364594e1c1b6856958b3e61e3ca22c140a"}, {file = "regex-2022.9.11-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c5ba2e8c3d9ef1c1d745b4c9055283241c366ff8528494af4bf0224499a54712"},
{file = "regex-2022.8.17-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8e8ec94d1b1a0a297c2c69a0bf000baf9a79607ca0c084f577f811a9b447c319"}, {file = "regex-2022.9.11-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c9e18ff1a5ccf925ce800749d09a40ff7c20bcd47a7d53851880b5fedf5a591"},
{file = "regex-2022.8.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4bdfd016ab12c4075ef93f025b3cf4c8962b9b7a5e52bb7039ab64cb7755930c"}, {file = "regex-2022.9.11-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:53190d6cf1a11cc7fa9f7f9f9c753c95ddad7d60eb4801cf5716b4f98216a82d"},
{file = "regex-2022.8.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cb0c9a1476d279524538ba9a00ecec9eadcef31a6a60b2c8bd2f29f62044a559"}, {file = "regex-2022.9.11-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ee677f27f1a464c851ea1dec5f7a4b3fe80b404895891adc442ac42fb9f7d178"},
{file = "regex-2022.8.17-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25bffa248b99b53a61b1f20fc7d19f711e38e9f0bc90d44c26670f8dc282ad7d"}, {file = "regex-2022.9.11-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:f5bf95f34aea88a745a3cd52b950a54152a85c246dba13d84abf192e12b941a0"},
{file = "regex-2022.8.17-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0843cc977b9cc00eb2299b624db6481d25e7f5b093f7a7c2bb727028d4a26eda"}, {file = "regex-2022.9.11-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:bee699bee0f364af37729142abb0a0816f9785ba0bb968101dd9d8246da94301"},
{file = "regex-2022.8.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:4e12a3c2d4781ee5d03f229c940934fa1e4ea4f4995e68ab97a2815b139e0804"}, {file = "regex-2022.9.11-cp37-cp37m-musllinux_1_1_ppc64le.whl", hash = "sha256:b2bcaf9b72c36c4e55b2f279f8747a6ac5615a3486905b9188299fefaa5bcb09"},
{file = "regex-2022.8.17-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:dc32029b9cc784a529f9201289d4f841cc24a2ae3126a112cd467bc41bbc2f10"}, {file = "regex-2022.9.11-cp37-cp37m-musllinux_1_1_s390x.whl", hash = "sha256:aa713ac41c6f1e3fecca3a2608aeb35b1ba1feba7f0c52710ea1929609990c89"},
{file = "regex-2022.8.17-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:4c6554073e3e554fbb3dff88376ada3da32ca789ea1b9e381f684d49ddb61199"}, {file = "regex-2022.9.11-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:70f0646605177ebd4c3e658ba35a366fe9a33e67325cdd0b920c48ea768d8a82"},
{file = "regex-2022.8.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:2ada67e02fa3fcca9e3b90cf24c2c6bc77f0abc126209937956aea10eeba40c7"}, {file = "regex-2022.9.11-cp37-cp37m-win32.whl", hash = "sha256:cfca724c38649c2b0efb56759d0f988e1b534f4148f90065578713400a053771"},
{file = "regex-2022.8.17-cp38-cp38-win32.whl", hash = "sha256:1418d3506a9582b23a27373f125ea2b0da523c581e7cf678a6f036254d134faa"}, {file = "regex-2022.9.11-cp37-cp37m-win_amd64.whl", hash = "sha256:b1629547bacb14fbd27f53f627b3adb7ec31e63c42b89d7c3ab66bb94d5d50b3"},
{file = "regex-2022.8.17-cp38-cp38-win_amd64.whl", hash = "sha256:2c198921afc811bc0f105c6e5150fbdebf9520c9b7d43cfc0ab156ca97f506d7"}, {file = "regex-2022.9.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:48e4cf239875093790fa269d7a4f0cd532748d502488231512b3956d7f03295b"},
{file = "regex-2022.8.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7658d2dfc1dabfb008ffe12ae47b98559e2aedd8237bee12f5aafb74d90479e3"}, {file = "regex-2022.9.11-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:eba4646a81f88542568ad42c8b62819f476dbe786471f5dd8cd8b3f1d8d20df3"},
{file = "regex-2022.8.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:242f546fc5e49bb7395624ac3b4fc168bf454e11ace9804c58c4c3a90d84e38f"}, {file = "regex-2022.9.11-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06b3c5a0e12048902575e7ec41717807db07c06f94f8ac7ca2ca577f3412d48b"},
{file = "regex-2022.8.17-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7b88bc7306136b123fd1a9beed16ca02900ee31d1c36e73fa33d9e525a5562d"}, {file = "regex-2022.9.11-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:37a47d96224cadaa79cf64b10aad85604787fffb8913ec39bcad985f73588a55"},
{file = "regex-2022.8.17-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2240fce3af236e4586a045c1be8bbf16c4f8831e68b7df918b72fc31a80143be"}, {file = "regex-2022.9.11-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dc868967051010170eee023053d53255901e5f54dd0c34414c3914ab6504c179"},
{file = "regex-2022.8.17-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e0b55651db770b4b5a6c7d015f24d1a6ede307296bbdf0c47fc5f6a6adc7abee"}, {file = "regex-2022.9.11-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fdce51c6961ff19e6800b7ea706c7836a0eca932053b0c4a3fe19b16e556092d"},
{file = "regex-2022.8.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9668da78bcc219542467f51c2cd01894222be6aceec4b5efb806705900b794d8"}, {file = "regex-2022.9.11-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f95532fc075f5f416d1376ed5c5d2c67fbbc69d99abc80575a15ff3666b72c7"},
{file = "regex-2022.8.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e7c8f9f8824143c219dd93cdc733c20d2c12f154034c89bcb4911db8e45bd92"}, {file = "regex-2022.9.11-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a1115967b13a1fe5388ede91caf296aa22e05a9f1b2fe4ab99f41bdf14af981a"},
{file = "regex-2022.8.17-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c2b6404631b22617b5127c6de2355393ccda693ca733a098b6802e7dabb3457a"}, {file = "regex-2022.9.11-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:212090f37c65381933643a1a8b94d5d73a10027415a7c4baa3cae6549ad49ab2"},
{file = "regex-2022.8.17-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:45cb798095b886e4df6ff4a1f7661eb70620ccdef127e3c3e00a1aaa22d30e53"}, {file = "regex-2022.9.11-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:39139c1921cfebe4012149561cb3b8b46adad533e45fc306f8ba7ce5c112dac3"},
{file = "regex-2022.8.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:777ceea2860a48e9e362a4e2a9a691782ea97bd05c24627c92e876fdd2c22e61"}, {file = "regex-2022.9.11-cp38-cp38-musllinux_1_1_ppc64le.whl", hash = "sha256:1c3133a547b78886e2cc01a2fa1c0a0dae9b5a7201cbaec98d4e33e593536d17"},
{file = "regex-2022.8.17-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:99a7c5786de9e92ff5ffee2e8bed745f5d25495206f3f14656c379031e518334"}, {file = "regex-2022.9.11-cp38-cp38-musllinux_1_1_s390x.whl", hash = "sha256:6ad8cbbb653d41b3ee0079d02f65d811f8764ffdc138a7207bdd562d30299856"},
{file = "regex-2022.8.17-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:d76e585368388d99ddd2f95989e6ac80a8fe23115e93931faad99fa34550612f"}, {file = "regex-2022.9.11-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:01a01a69f1f82691675c35ec282f44ad2d0a2c27558f6238f8cd2d29616a150e"},
{file = "regex-2022.8.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a25d251546acb5edb1635631c4ae0e330fa4ec7c6316c01d256728fbfb9bbff2"}, {file = "regex-2022.9.11-cp38-cp38-win32.whl", hash = "sha256:0d7df2af1341cee32a03466b59b37c418bedb83863b5feba8ec4c70ad5de3dee"},
{file = "regex-2022.8.17-cp39-cp39-win32.whl", hash = "sha256:fac611bde2609a46fcbd92da7171286faa2f5c191f84d22f61cd7dc27213f51d"}, {file = "regex-2022.9.11-cp38-cp38-win_amd64.whl", hash = "sha256:4a0c807a70ea71b168ac0d358e26e97c4a0af06e6ee99e757a8e7d19ac18994a"},
{file = "regex-2022.8.17-cp39-cp39-win_amd64.whl", hash = "sha256:ccb986e80674c929f198464bce55e995178dea26833421e2479ff04a6956afac"}, {file = "regex-2022.9.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:27d53e5b3cc409e643ef42cfffffd160bec28111aa60634c251e871d8e542416"},
{file = "regex-2022.8.17.tar.gz", hash = "sha256:5c77eab46f3a2b2cd8bbe06467df783543bf7396df431eb4a144cc4b89e9fb3c"}, {file = "regex-2022.9.11-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:93fe7b56a44072828a49b15f74c0915ae5e301ec9caaedbe3c70c45df67389c6"},
{file = "regex-2022.9.11-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:577043629a33ab932b484139a097cf26b19e64b833bde7a294f67077ddb4918e"},
{file = "regex-2022.9.11-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c77ce22edfa612d3d0443fe600895431dc77ca1cfd9dcd3edaba48b28834fa90"},
{file = "regex-2022.9.11-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c8bf18398af539ba6550a8086d5b57db9580c36190a0644f1049463855b3aac7"},
{file = "regex-2022.9.11-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:54d9219992e4c849279297d4e3b076a01eca55a75d54e0d80d5c391f644ae7f3"},
{file = "regex-2022.9.11-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f01b342ec64d0e47915c70f14596c2e06d126b92c3ea420b6cc0992c43a4312"},
{file = "regex-2022.9.11-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0824f163c26bc1684ebd9fe4d8c77ae6aceb4aa560c06cd050429b028dc5c3e2"},
{file = "regex-2022.9.11-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:27d73b632648d392fd4003d7e19aedacd6ac1613f41abadef9ac5681b1da0a24"},
{file = "regex-2022.9.11-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:386d82efc745dd9676a4d372c57f8a0229482ad31d400024b6b5fad67bdb6496"},
{file = "regex-2022.9.11-cp39-cp39-musllinux_1_1_ppc64le.whl", hash = "sha256:97110faa16598a488ddfe3022b5bd9b4db1d2ce1ee72db080876a80911feefad"},
{file = "regex-2022.9.11-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:5b10a18f36add26752140ba48278198168c92d26c3b4d080079bc584fce778bf"},
{file = "regex-2022.9.11-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a31e7c3cd447f29cce5a5a5270a0c5d355c8f7e55266346f1b71cbe61c35756e"},
{file = "regex-2022.9.11-cp39-cp39-win32.whl", hash = "sha256:841d93b90d71854378fc5ac6b52fb952428370f7672f20b12efcb93aa932b340"},
{file = "regex-2022.9.11-cp39-cp39-win_amd64.whl", hash = "sha256:0d86877f721d671ec2e368341c48b762883e1ede39fc1fb78ee68b8cf0c82696"},
{file = "regex-2022.9.11.tar.gz", hash = "sha256:36dc03da451c2aef9a3ea521a453faa43474fc6c1d8b46706aee6c31a57d3552"},
]
requests = [
{file = "requests-2.28.1-py3-none-any.whl", hash = "sha256:8fefa2a1a1365bf5520aac41836fbee479da67864514bdb821f31ce07ce65349"},
{file = "requests-2.28.1.tar.gz", hash = "sha256:7c5599b102feddaa661c826c56ab4fee28bfd17f5abca1ebbe3e7f19d7c97983"},
]
requests-oauthlib = [
{file = "requests-oauthlib-1.3.1.tar.gz", hash = "sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a"},
{file = "requests_oauthlib-1.3.1-py2.py3-none-any.whl", hash = "sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5"},
] ]
sentry-sdk = [ sentry-sdk = [
{file = "sentry-sdk-1.9.8.tar.gz", hash = "sha256:ef4b4d57631662ff81e15c22bf007f7ce07c47321648c8e601fbd22950ed1a79"}, {file = "sentry-sdk-1.9.8.tar.gz", hash = "sha256:ef4b4d57631662ff81e15c22bf007f7ce07c47321648c8e601fbd22950ed1a79"},

View File

@ -1,6 +1,6 @@
[tool.poetry] [tool.poetry]
name = "divent" name = "divent"
version = "1.0.5" version = "2.0.0"
description = "The discord scheduled event calendar generator" description = "The discord scheduled event calendar generator"
authors = ["Xéfir Destiny"] authors = ["Xéfir Destiny"]
license = "WTFPL" license = "WTFPL"
@ -17,16 +17,17 @@ disnake = "2.5.2"
ics = "0.8.0.dev0" ics = "0.8.0.dev0"
python-dotenv = "0.21.0" python-dotenv = "0.21.0"
quart = "0.18.0" quart = "0.18.0"
requests-oauthlib = "1.3.1"
sentry-sdk = "1.9.8" sentry-sdk = "1.9.8"
uvicorn = "0.18.3" uvicorn = "0.18.3"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
flake8 = "5.0.4"
black = "22.8.0" black = "22.8.0"
mypy = "0.971" djlint = "1.12.3"
flake8 = "5.0.4"
flake8-alphabetize = "0.0.17" flake8-alphabetize = "0.0.17"
flake8-black = "0.3.3" flake8-black = "0.3.3"
djlint = "1.12.3" mypy = "0.971"
[build-system] [build-system]
requires = ["poetry-core>=1.0.0"] requires = ["poetry-core>=1.0.0"]