Compare commits
No commits in common. "master" and "4.0.0" have entirely different histories.
@ -4,14 +4,14 @@ on: [push]
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
container: python:3.12.6
|
||||
container: python:3.11
|
||||
steps:
|
||||
- run: apt-get update
|
||||
- run: apt-get install -y git nodejs
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Gr1N/setup-poetry@v9
|
||||
- uses: Gr1N/setup-poetry@v8
|
||||
- run: poetry install
|
||||
- run: poetry run ruff check .
|
||||
- run: poetry run flake8 .
|
||||
- run: poetry run mypy .
|
||||
- run: poetry run djlint .
|
||||
|
||||
@ -35,22 +35,22 @@ jobs:
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- uses: docker/build-push-action@v6
|
||||
- uses: docker/build-push-action@v5
|
||||
with:
|
||||
push: ${{ gitea.ref_name == gitea.event.repository.default_branch || gitea.ref_type == 'tag' }}
|
||||
push: ${{ gitea.ref == 'refs/heads/master' || startsWith(gitea.ref, 'refs/tags') }}
|
||||
tags: ${{ steps.meta.outputs.tags }}
|
||||
labels: ${{ steps.meta.outputs.labels }}
|
||||
|
||||
pypi:
|
||||
runs-on: ubuntu-latest
|
||||
container: python:3.12.6
|
||||
container: python:3.11
|
||||
needs: [lint]
|
||||
if: gitea.ref_type == 'tag'
|
||||
if: startsWith(gitea.ref, 'refs/tags')
|
||||
env:
|
||||
POETRY_PYPI_TOKEN_PYPI: ${{ secrets.POETRY_PYPI_TOKEN_PYPI }}
|
||||
steps:
|
||||
- run: apt-get update
|
||||
- run: apt-get install -y git nodejs
|
||||
- uses: actions/checkout@v4
|
||||
- uses: Gr1N/setup-poetry@v9
|
||||
- uses: Gr1N/setup-poetry@v8
|
||||
- run: poetry publish --build
|
||||
|
6
.gitignore
vendored
6
.gitignore
vendored
@ -107,10 +107,8 @@ ipython_config.py
|
||||
#pdm.lock
|
||||
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
||||
# in version control.
|
||||
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
||||
# https://pdm.fming.dev/#use-with-ide
|
||||
.pdm.toml
|
||||
.pdm-python
|
||||
.pdm-build/
|
||||
|
||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
||||
__pypackages__/
|
||||
@ -160,4 +158,4 @@ cython_debug/
|
||||
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
||||
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
||||
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
||||
#.idea/
|
||||
.idea/
|
||||
|
@ -1,10 +1,10 @@
|
||||
FROM python:3.12.6 as build
|
||||
FROM python:3.11.6 as build
|
||||
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN pip install poetry && poetry build
|
||||
|
||||
FROM python:3.12.6
|
||||
FROM python:3.11.5
|
||||
|
||||
COPY --from=build /app/dist /tmp/dist
|
||||
RUN pip install /tmp/dist/*.whl && rm -rf /tmp/dist
|
||||
|
@ -1,3 +0,0 @@
|
||||
from divent.bot import run
|
||||
|
||||
run()
|
@ -3,17 +3,18 @@ import logging
|
||||
from datetime import datetime, timedelta
|
||||
from functools import wraps
|
||||
from os import getenv, path
|
||||
from typing import Dict, Optional, Union
|
||||
from typing import Dict, Optional
|
||||
|
||||
from disnake import Asset, Client, Guild, Intents, Member, User
|
||||
from disnake import Asset, Client, Guild
|
||||
from disnake.guild_scheduled_event import GuildScheduledEvent
|
||||
from dotenv import load_dotenv
|
||||
from hypercorn.middleware import ProxyFixMiddleware
|
||||
from ics import Calendar, ContentLine, Event
|
||||
from ics.alarm import DisplayAlarm
|
||||
from oauthlib.oauth2 import OAuth2Error
|
||||
from quart import Quart, redirect, render_template, request, session, url_for
|
||||
from requests_oauthlib import OAuth2Session # type: ignore
|
||||
from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware
|
||||
|
||||
|
||||
load_dotenv()
|
||||
|
||||
@ -35,51 +36,17 @@ API_BASE_URL = getenv("API_BASE_URL", "https://discordapp.com/api")
|
||||
AUTHORIZATION_BASE_URL = f"{API_BASE_URL}/oauth2/authorize"
|
||||
TOKEN_URL = f"{API_BASE_URL}/oauth2/token"
|
||||
|
||||
CATALOG_CACHE = {}
|
||||
EVENTS_CACHE = {}
|
||||
|
||||
|
||||
class Discord(Client):
|
||||
async def on_ready(self):
|
||||
print(f"Logged on as {self.user}!", flush=True)
|
||||
|
||||
for guild in self.guilds:
|
||||
for scheduled_event in guild.scheduled_events:
|
||||
EVENTS_CACHE[scheduled_event.id] = [
|
||||
member.id
|
||||
for member in await scheduled_event.fetch_users().flatten()
|
||||
]
|
||||
|
||||
print("Events synchronised!", flush=True)
|
||||
|
||||
async def on_guild_scheduled_event_subscribe(
|
||||
self, event: GuildScheduledEvent, user: Union[Member, User]
|
||||
):
|
||||
EVENTS_CACHE[event.id].append(user.id)
|
||||
|
||||
async def on_guild_scheduled_event_unsubscribe(
|
||||
self, event: GuildScheduledEvent, user: Union[Member, User]
|
||||
):
|
||||
EVENTS_CACHE[event.id].remove(user.id)
|
||||
|
||||
async def on_guild_scheduled_event_create(self, event: GuildScheduledEvent):
|
||||
EVENTS_CACHE[event.id] = [
|
||||
member.id for member in await event.fetch_users().flatten()
|
||||
]
|
||||
|
||||
async def on_guild_scheduled_event_delete(self, event: GuildScheduledEvent):
|
||||
EVENTS_CACHE.pop(event.id)
|
||||
|
||||
|
||||
intents = Intents.default()
|
||||
intents.guild_scheduled_events = True
|
||||
intents.members = True
|
||||
client = Discord(intents=intents)
|
||||
|
||||
client = Discord()
|
||||
app = Quart(__name__)
|
||||
app.config["SECRET_KEY"] = OAUTH2_CLIENT_SECRET
|
||||
app.config["EXPLAIN_TEMPLATE_LOADING"] = QUART_DEBUG
|
||||
app.asgi_app = ProxyFixMiddleware(app.asgi_app) # type: ignore
|
||||
app.asgi_app = ProxyHeadersMiddleware(app.asgi_app, "*") # type: ignore
|
||||
|
||||
|
||||
def get_guild_by_id(guild_id: str) -> Optional[Guild]:
|
||||
@ -90,6 +57,9 @@ def get_guild_by_id(guild_id: str) -> Optional[Guild]:
|
||||
return None
|
||||
|
||||
|
||||
CATALOG_CACHE = {}
|
||||
|
||||
|
||||
@app.errorhandler(500)
|
||||
async def errorhandler(error: Exception):
|
||||
print(f"\33[31m{error}\33[m", flush=True)
|
||||
@ -251,10 +221,7 @@ async def subscribe(entity_id: str):
|
||||
entity_id=guild.vanity_url_code or guild.id,
|
||||
)
|
||||
|
||||
try:
|
||||
user = await client.get_or_fetch_user(int(entity_id))
|
||||
except ValueError:
|
||||
return redirect(url_for(".login"))
|
||||
|
||||
if user and str(user.id) == entity_id:
|
||||
return await render_template(
|
||||
@ -314,10 +281,7 @@ async def ical(entity_id: str):
|
||||
|
||||
return calendar.serialize()
|
||||
|
||||
try:
|
||||
user = await client.get_or_fetch_user(int(entity_id))
|
||||
except ValueError:
|
||||
return redirect(url_for(".login"))
|
||||
|
||||
if user:
|
||||
calendar = Calendar()
|
||||
@ -331,8 +295,12 @@ async def ical(entity_id: str):
|
||||
)
|
||||
|
||||
for guild in client.guilds:
|
||||
if await guild.get_or_fetch_member(int(entity_id)):
|
||||
for scheduled_event in guild.scheduled_events:
|
||||
if user.id in EVENTS_CACHE[scheduled_event.id]:
|
||||
if user.id in [
|
||||
member.id
|
||||
for member in await scheduled_event.fetch_users().flatten()
|
||||
]:
|
||||
event = make_event(scheduled_event)
|
||||
calendar.events.append(event)
|
||||
|
||||
@ -341,6 +309,7 @@ async def ical(entity_id: str):
|
||||
return redirect(url_for(".login"))
|
||||
|
||||
|
||||
def run():
|
||||
client.loop.create_task(client.start(DISCORD_TOKEN))
|
||||
app.run("0.0.0.0", loop=client.loop)
|
||||
def __main__():
|
||||
quart_task = client.loop.create_task(app.run_task("0.0.0.0"))
|
||||
quart_task.add_done_callback(lambda f: client.loop.stop())
|
||||
client.run(DISCORD_TOKEN)
|
||||
|
1678
poetry.lock
generated
1678
poetry.lock
generated
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
[tool.poetry]
|
||||
name = "divent"
|
||||
version = "4.1.4"
|
||||
version = "4.0.0"
|
||||
description = "The discord scheduled event calendar generator"
|
||||
authors = ["Xéfir Destiny <xefir@crystalyx.net>"]
|
||||
license = "WTFPL"
|
||||
@ -9,29 +9,34 @@ homepage = "https://divent.crystalyx.net/"
|
||||
repository = "https://git.crystalyx.net/Xefir/Divent"
|
||||
|
||||
[tool.poetry.scripts]
|
||||
divent = 'divent.bot:run'
|
||||
divent = 'divent.bot:__main__'
|
||||
|
||||
[tool.poetry.dependencies]
|
||||
python = ">=3.8,<4.0"
|
||||
disnake = "^2.9.2"
|
||||
python = ">=3.8.1,<3.12"
|
||||
disnake = "^2.9.1"
|
||||
ics = "0.8.0.dev0"
|
||||
python-dotenv = "^1.0.1"
|
||||
quart = "^0.19.6"
|
||||
requests-oauthlib = "^2.0.0"
|
||||
python-dotenv = "^1.0.0"
|
||||
quart = "^0.19.3"
|
||||
requests-oauthlib = "^1.3.1"
|
||||
uvicorn = "^0.24.0"
|
||||
|
||||
[tool.poetry.dev-dependencies]
|
||||
djlint = "^1.35.2"
|
||||
mypy = "^1.11.2"
|
||||
ruff = "^0.6.5"
|
||||
types-oauthlib = "^3.2.0"
|
||||
black = "^23.10.1"
|
||||
djlint = "^1.34.0"
|
||||
flake8 = "^6.1.0"
|
||||
flake8-alphabetize = "^0.0.21"
|
||||
flake8-black = "^0.3.6"
|
||||
flake8-pyproject = "^1.2.3"
|
||||
mypy = "^1.6.1"
|
||||
types-oauthlib = "^3.2.0.10"
|
||||
|
||||
[tool.flake8]
|
||||
max-line-length = 88
|
||||
|
||||
[build-system]
|
||||
requires = ["poetry-core>=1.0.0"]
|
||||
build-backend = "poetry.core.masonry.api"
|
||||
|
||||
[tool.ruff.lint]
|
||||
select = ["E", "F", "I"]
|
||||
|
||||
[tool.djlint]
|
||||
extension = "j2"
|
||||
profile = "jinja"
|
||||
|
Loading…
Reference in New Issue
Block a user