From a6025975a96fce8742a672112177684e3445d1c8 Mon Sep 17 00:00:00 2001 From: Michel Roux Date: Mon, 6 Nov 2023 21:56:09 +0100 Subject: [PATCH 1/5] Add option to subscribe to all personal events --- divent/bot.py | 95 ++++++++++++++++++++++----------- divent/templates/guilds.html.j2 | 10 ++-- divent/translations/fr.json | 1 + pyproject.toml | 2 +- 4 files changed, 71 insertions(+), 37 deletions(-) diff --git a/divent/bot.py b/divent/bot.py index b3305f4..f736965 100644 --- a/divent/bot.py +++ b/divent/bot.py @@ -6,6 +6,7 @@ from os import getenv, path from typing import Dict, Optional from disnake import Client, Guild +from disnake.guild_scheduled_event import GuildScheduledEvent from dotenv import load_dotenv from ics import Calendar, ContentLine, Event from ics.alarm import DisplayAlarm @@ -223,46 +224,78 @@ async def subscribe(guild_id: str): return await render_template("subscribe.html.j2", guild=guild) -@app.route("/.ics") -async def ical(guild_id: str): - guild = get_guild_by_id(guild_id) - if guild is None: - return redirect(url_for(".login")) +def make_event(scheduled_event: GuildScheduledEvent, guild_id: int) -> Event: + event = Event() - calendar = Calendar() + event.summary = scheduled_event.name + event.begin = scheduled_event.scheduled_start_time + event.end = scheduled_event.scheduled_end_time + event.duration = timedelta(hours=2) + event.uid = str(scheduled_event.id) + event.description = scheduled_event.description + event.url = f"https://discord.com/events/{guild_id}/{scheduled_event.id}" + event.location = ( + scheduled_event.entity_metadata.location + if scheduled_event.entity_metadata + else None + ) - calendar.extra.append(ContentLine(name="REFRESH-INTERVAL", value="PT1H")) - calendar.extra.append(ContentLine(name="X-PUBLISHED-TTL", value="PT1H")) + alarm = DisplayAlarm() + alarm.trigger = timedelta(hours=-1) + event.alarms.append(alarm) - calendar.extra.append(ContentLine(name="NAME", value=guild.name)) - calendar.extra.append(ContentLine(name="X-WR-CALNAME", value=guild.name)) + return event - if guild.description: - calendar.extra.append(ContentLine(name="DESCRIPTION", value=guild.description)) - calendar.extra.append(ContentLine(name="X-WR-CALDESC", value=guild.description)) - for scheduled_event in guild.scheduled_events: - event = Event() - event.summary = scheduled_event.name - event.begin = scheduled_event.scheduled_start_time - event.end = scheduled_event.scheduled_end_time - event.duration = timedelta(hours=2) - event.uid = str(scheduled_event.id) - event.description = scheduled_event.description - event.url = f"https://discord.com/events/{guild_id}/{scheduled_event.id}" - event.location = ( - scheduled_event.entity_metadata.location - if scheduled_event.entity_metadata - else None +@app.route("/.ics") +async def ical(entity_id: str): + guild = get_guild_by_id(entity_id) + + if guild: + calendar = Calendar() + + calendar.extra.append(ContentLine(name="REFRESH-INTERVAL", value="PT1H")) + calendar.extra.append(ContentLine(name="X-PUBLISHED-TTL", value="PT1H")) + + calendar.extra.append(ContentLine(name="NAME", value=guild.name)) + calendar.extra.append(ContentLine(name="X-WR-CALNAME", value=guild.name)) + + if guild.description: + calendar.extra.append( + ContentLine(name="DESCRIPTION", value=guild.description) + ) + calendar.extra.append( + ContentLine(name="X-WR-CALDESC", value=guild.description) + ) + + for scheduled_event in guild.scheduled_events: + event = make_event(scheduled_event, guild.id) + calendar.events.append(event) + + return calendar.serialize() + + user = client.get_or_fetch_user(int(entity_id)) + + if user: + calendar = Calendar() + + calendar.extra.append(ContentLine(name="REFRESH-INTERVAL", value="PT1H")) + calendar.extra.append(ContentLine(name="X-PUBLISHED-TTL", value="PT1H")) + + calendar.extra.append(ContentLine(name="NAME", value=client.user.display_name)) + calendar.extra.append( + ContentLine(name="X-WR-CALNAME", value=client.user.display_name) ) - alarm = DisplayAlarm() - alarm.trigger = timedelta(hours=-1) - event.alarms.append(alarm) + for guild in client.guilds: + if guild.get_or_fetch_member(int(entity_id)): + for scheduled_event in guild.scheduled_events: + event = make_event(scheduled_event, guild.id) + calendar.events.append(event) - calendar.events.append(event) + return calendar.serialize() - return calendar.serialize() + return redirect(url_for(".login")) def __main__(): diff --git a/divent/templates/guilds.html.j2 b/divent/templates/guilds.html.j2 index 26dde37..fac15f2 100644 --- a/divent/templates/guilds.html.j2 +++ b/divent/templates/guilds.html.j2 @@ -16,8 +16,12 @@

{{ client.user.display_name }}

+ + {{ _("For all your servers") }} + +
{{ _("OR") }}

{{ _('Choose a server:') }}

- @@ -29,7 +33,6 @@
{{ _("OR") }}
{{ _("Add the bot on your server") }} @@ -48,8 +51,5 @@ -
- -
{% endblock content %} diff --git a/divent/translations/fr.json b/divent/translations/fr.json index 2cdef39..fd945f6 100644 --- a/divent/translations/fr.json +++ b/divent/translations/fr.json @@ -5,6 +5,7 @@ "This will allow you to:": "Ceci te permettra de :", "Subscribe to a calendar on Google, Outlook, Apple or any ICS complient software": "T'abonner à un calendrier sur Google, Outlook, Apple ou tout autre logiciel compatible", "Throwing you to a new isekai world": "T'envoyer dans un monde fantaisiste armée d'une poêle à frire", + "For all your servers": "Pour tous tes serveurs", "Choose a server:": "Choisi un serveur :", "You must have": "Tu dois avoir la permission", "Manage Server": "Gérer le serveur", diff --git a/pyproject.toml b/pyproject.toml index 881ebda..db9dd28 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "divent" -version = "3.4.4" +version = "4.0.0" description = "The discord scheduled event calendar generator" authors = ["Xéfir Destiny "] license = "WTFPL" -- 2.45.2 From 14131d73ac9735ab8ce35751a38aab7722fbe1f8 Mon Sep 17 00:00:00 2001 From: Michel Roux Date: Mon, 6 Nov 2023 22:06:01 +0100 Subject: [PATCH 2/5] Update python version and fix aiohttp --- Dockerfile | 2 +- poetry.lock | 4 ++-- pyproject.toml | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2c2257b..bfa6a78 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.11.5 as build +FROM python:3.11.6 as build WORKDIR /app COPY . . diff --git a/poetry.lock b/poetry.lock index 997d12a..04ca0ed 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1649,5 +1649,5 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" -python-versions = "^3.8.1" -content-hash = "e4463ad986a3f8fafe36af53b741fe71dd1a78d65efb3e4240ac422688fca367" +python-versions = ">=3.8.1,<3.12" +content-hash = "30113574429e0ed0539ebe2850264eb819fb2a7af92310402c9eccbca33487ed" diff --git a/pyproject.toml b/pyproject.toml index db9dd28..6e49100 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,7 +12,7 @@ repository = "https://git.crystalyx.net/Xefir/Divent" divent = 'divent.bot:__main__' [tool.poetry.dependencies] -python = "^3.8.1" +python = ">=3.8.1,<3.12" disnake = "^2.9.1" ics = "0.8.0.dev0" python-dotenv = "^1.0.0" -- 2.45.2 From 0f42bdc50b34ac3d07cf7fc5d5f4eb5756fc22b6 Mon Sep 17 00:00:00 2001 From: Michel Roux Date: Tue, 7 Nov 2023 01:26:12 +0100 Subject: [PATCH 3/5] fix remaining bugs --- divent/bot.py | 69 +++++++++++++++++------------- divent/templates/base.html.j2 | 6 +-- divent/templates/error.html.j2 | 8 ++-- divent/templates/footer.html.j2 | 8 ++-- divent/templates/guilds.html.j2 | 25 +++++------ divent/templates/index.html.j2 | 12 +++--- divent/templates/subscribe.html.j2 | 20 ++++----- divent/translations/fr.json | 1 - 8 files changed, 77 insertions(+), 72 deletions(-) diff --git a/divent/bot.py b/divent/bot.py index f736965..d7c2b3b 100644 --- a/divent/bot.py +++ b/divent/bot.py @@ -5,7 +5,7 @@ from functools import wraps from os import getenv, path from typing import Dict, Optional -from disnake import Client, Guild +from disnake import Asset, Client, Guild from disnake.guild_scheduled_event import GuildScheduledEvent from dotenv import load_dotenv from ics import Calendar, ContentLine, Event @@ -117,17 +117,11 @@ def days_before_failure() -> int: 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 def context_processor(): return dict( _=i18n, client=client, - cdn_avatar_url=cdn_avatar_url, days_before_failure=days_before_failure(), ) @@ -180,12 +174,10 @@ async def callback(): @app.route("/guilds") @login_required async def guilds(): - guild = get_guild_by_id(request.args.get("guild")) + guild = request.args.get("guild") if guild: - return redirect( - url_for(".subscribe", guild_id=guild.vanity_url_code or guild.id) - ) + return redirect(url_for(".subscribe", entity_id=guild)) try: discord = make_session(token=session.get("oauth2_token")) @@ -201,27 +193,42 @@ async def guilds(): common_guilds.append(bot_guild) return await render_template( - "guilds.html.j2", user=user, common_guilds=common_guilds + "guilds.html.j2", + user=user, + avatar=Asset._from_avatar(None, user["id"], user["avatar"]), + common_guilds=common_guilds, ) -@app.route("/subscribe/") +@app.route("/subscribe/") @login_required -async def subscribe(guild_id: str): - guild = get_guild_by_id(guild_id) - if guild is None: - return redirect(url_for(".login")) +async def subscribe(entity_id: str): + guild = get_guild_by_id(entity_id) - try: - discord = make_session(token=session.get("oauth2_token")) - user_guilds = discord.get(f"{API_BASE_URL}/users/@me/guilds").json() - except OAuth2Error: - return redirect(url_for(".login")) + if guild: + try: + discord = make_session(token=session.get("oauth2_token")) + user_guilds = discord.get(f"{API_BASE_URL}/users/@me/guilds").json() + except OAuth2Error: + return redirect(url_for(".login")) - if not any(str(guild.id) == user_guild["id"] for user_guild in user_guilds): - return redirect(url_for(".login")) + 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", + avatar=guild.icon, + entity_id=guild.vanity_url_code or guild.id, + ) + + user = await client.get_or_fetch_user(int(entity_id)) + + if user and str(user.id) == entity_id: + return await render_template( + "subscribe.html.j2", avatar=user.avatar, entity_id=user.id + ) + + return redirect(url_for(".login")) def make_event(scheduled_event: GuildScheduledEvent, guild_id: int) -> Event: @@ -274,7 +281,7 @@ async def ical(entity_id: str): return calendar.serialize() - user = client.get_or_fetch_user(int(entity_id)) + user = await client.get_or_fetch_user(int(entity_id)) if user: calendar = Calendar() @@ -288,10 +295,14 @@ async def ical(entity_id: str): ) for guild in client.guilds: - if guild.get_or_fetch_member(int(entity_id)): + if await guild.get_or_fetch_member(int(entity_id)): for scheduled_event in guild.scheduled_events: - event = make_event(scheduled_event, guild.id) - calendar.events.append(event) + if user.id in [ + member.id + for member in await scheduled_event.fetch_users().flatten() + ]: + event = make_event(scheduled_event, guild.id) + calendar.events.append(event) return calendar.serialize() diff --git a/divent/templates/base.html.j2 b/divent/templates/base.html.j2 index 5986387..f267608 100644 --- a/divent/templates/base.html.j2 +++ b/divent/templates/base.html.j2 @@ -6,11 +6,11 @@ - {{ client.user.display_name }} - {{ _('The discord scheduled event calendar generator') }} + {{ client.user.display_name }} - {{ _("The discord scheduled event calendar generator") }} + href="{{ url_for('static', filename='css/font-awesome.min.css') }}" /> + href="{{ url_for('static', filename='css/global.css') }}" />
diff --git a/divent/templates/error.html.j2 b/divent/templates/error.html.j2 index af1b801..007e207 100644 --- a/divent/templates/error.html.j2 +++ b/divent/templates/error.html.j2 @@ -3,17 +3,17 @@
{{ _('Link is dead') }} + width="173" />

{{ error }}
{% endblock content %} diff --git a/divent/templates/footer.html.j2 b/divent/templates/footer.html.j2 index f266de0..ef1f446 100644 --- a/divent/templates/footer.html.j2 +++ b/divent/templates/footer.html.j2 @@ -2,7 +2,7 @@
  • - {{ _('Add author on Discord') }} + {{ _("Add author on Discord") }}
  • @@ -16,17 +16,17 @@
  • - {{ _('View the source code') }} + {{ _("View the source code") }}
  • - {{ _('Host it yourself') }} + {{ _("Host it yourself") }}
  • - {{ _('Next castastrophic life failure in about %days% days') | replace('%days%', days_before_failure) }} + {{ _("Next castastrophic life failure in about %days% days") | replace('%days%', days_before_failure) }}
  • diff --git a/divent/templates/guilds.html.j2 b/divent/templates/guilds.html.j2 index fac15f2..b45408b 100644 --- a/divent/templates/guilds.html.j2 +++ b/divent/templates/guilds.html.j2 @@ -4,31 +4,26 @@
    {{ _('Bot Logo') }} + height="80" /> - {{ _('User Avatar') }} + height="80" />

    {{ client.user.display_name }}

    - - {{ _("For all your servers") }} - +

    {{ _("The discord scheduled event calendar generator") }}

    +
    + {{ _("For all your servers") }}
    {{ _("OR") }}
    -

    {{ _('Choose a server:') }}

    {{ _("OR") }}
    diff --git a/divent/templates/index.html.j2 b/divent/templates/index.html.j2 index 65d1797..75c1869 100644 --- a/divent/templates/index.html.j2 +++ b/divent/templates/index.html.j2 @@ -4,24 +4,24 @@
    {{ _('Bot Logo') }} + height="80" />

    {{ client.user.display_name }}

    -

    {{ _('The discord scheduled event calendar generator') }}

    +

    {{ _("The discord scheduled event calendar generator") }}


    -

    {{ _('This will allow you to:') }}

    +

    {{ _("This will allow you to:") }}

    • - {{ _('Subscribe to a calendar on Google, Outlook, Apple or any ICS complient software') }} + {{ _("Subscribe to a calendar on Google, Outlook, Apple or any ICS complient software") }}
    • - {{ _('Throwing you to a new isekai world') }} + {{ _("Throwing you to a new isekai world") }}
    diff --git a/divent/templates/subscribe.html.j2 b/divent/templates/subscribe.html.j2 index 4f7e833..da3fd7b 100644 --- a/divent/templates/subscribe.html.j2 +++ b/divent/templates/subscribe.html.j2 @@ -3,25 +3,25 @@
    {{ _('Bot Logo') }} + height="80" /> - {{ _('Guild Logo') }} + height="80" />

    {{ client.user.display_name }}

    -

    {{ _('The discord scheduled event calendar generator') }}

    +

    {{ _("The discord scheduled event calendar generator") }}


    diff --git a/divent/translations/fr.json b/divent/translations/fr.json index fd945f6..b49e183 100644 --- a/divent/translations/fr.json +++ b/divent/translations/fr.json @@ -6,7 +6,6 @@ "Subscribe to a calendar on Google, Outlook, Apple or any ICS complient software": "T'abonner à un calendrier sur Google, Outlook, Apple ou tout autre logiciel compatible", "Throwing you to a new isekai world": "T'envoyer dans un monde fantaisiste armée d'une poêle à frire", "For all your servers": "Pour tous tes serveurs", - "Choose a server:": "Choisi un serveur :", "You must have": "Tu dois avoir la permission", "Manage Server": "Gérer le serveur", "permission on this server to perform this action": "sur ce serveur pour effectuer cette action", -- 2.45.2 From f795637848d5303800bae0490b98f6ee771a4085 Mon Sep 17 00:00:00 2001 From: Michel Roux Date: Tue, 7 Nov 2023 01:32:47 +0100 Subject: [PATCH 4/5] no need for guild --- divent/bot.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/divent/bot.py b/divent/bot.py index d7c2b3b..34571ba 100644 --- a/divent/bot.py +++ b/divent/bot.py @@ -231,7 +231,7 @@ async def subscribe(entity_id: str): return redirect(url_for(".login")) -def make_event(scheduled_event: GuildScheduledEvent, guild_id: int) -> Event: +def make_event(scheduled_event: GuildScheduledEvent) -> Event: event = Event() event.summary = scheduled_event.name @@ -240,7 +240,7 @@ def make_event(scheduled_event: GuildScheduledEvent, guild_id: int) -> Event: event.duration = timedelta(hours=2) event.uid = str(scheduled_event.id) event.description = scheduled_event.description - event.url = f"https://discord.com/events/{guild_id}/{scheduled_event.id}" + event.url = scheduled_event.url event.location = ( scheduled_event.entity_metadata.location if scheduled_event.entity_metadata @@ -276,7 +276,7 @@ async def ical(entity_id: str): ) for scheduled_event in guild.scheduled_events: - event = make_event(scheduled_event, guild.id) + event = make_event(scheduled_event) calendar.events.append(event) return calendar.serialize() @@ -301,7 +301,7 @@ async def ical(entity_id: str): member.id for member in await scheduled_event.fetch_users().flatten() ]: - event = make_event(scheduled_event, guild.id) + event = make_event(scheduled_event) calendar.events.append(event) return calendar.serialize() -- 2.45.2 From 1d29557ab50c8711310d87c7a227888e0e749eb1 Mon Sep 17 00:00:00 2001 From: Michel Roux Date: Tue, 7 Nov 2023 01:33:43 +0100 Subject: [PATCH 5/5] Reformat --- divent/templates/subscribe.html.j2 | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/divent/templates/subscribe.html.j2 b/divent/templates/subscribe.html.j2 index da3fd7b..09064b6 100644 --- a/divent/templates/subscribe.html.j2 +++ b/divent/templates/subscribe.html.j2 @@ -7,10 +7,7 @@ width="80" height="80" /> - {{ _( + {{ _(

    {{ client.user.display_name }} -- 2.45.2