easterobot 1.1.0__py3-none-any.whl → 1.1.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -5,10 +5,10 @@ import functools
5
5
  import logging
6
6
  from collections.abc import Coroutine
7
7
  from time import time
8
- from typing import Any, Callable, TypeVar, Union, cast
8
+ from typing import Any, Callable, Optional, TypeVar, Union, cast
9
9
 
10
10
  import discord
11
- from discord import app_commands
11
+ from discord import Permissions, app_commands
12
12
  from sqlalchemy import and_, delete
13
13
  from sqlalchemy.ext.asyncio import AsyncSession
14
14
  from typing_extensions import Concatenate, ParamSpec
@@ -54,19 +54,22 @@ Interaction = discord.Interaction[Easterobot]
54
54
  Coro = Coroutine[Any, Any, T]
55
55
 
56
56
 
57
- def controlled_command(
58
- *, cooldown: bool = True, **perms: bool
57
+ def controlled_command( # noqa: C901, PLR0915
58
+ *,
59
+ cooldown: bool = True,
60
+ channel_permissions: Optional[dict[str, bool]] = None,
61
+ **perms: bool,
59
62
  ) -> Callable[
60
63
  [Callable[Concatenate[Context, P], Coro[None]]],
61
64
  Callable[Concatenate[Interaction, P], Coro[None]],
62
65
  ]:
63
66
  """Add a cooldown and permission check."""
64
67
 
65
- def decorator(
68
+ def decorator( # noqa: C901
66
69
  f: Callable[Concatenate[Context, P], Coro[None]],
67
70
  ) -> Callable[Concatenate[Interaction, P], Coro[None]]:
68
71
  @functools.wraps(f)
69
- async def decorated(
72
+ async def decorated( # noqa: C901, PLR0911, PLR0912
70
73
  interaction: Interaction, *args: P.args, **kwargs: P.kwargs
71
74
  ) -> None:
72
75
  # Check if interaction is valid
@@ -91,6 +94,28 @@ def controlled_command(
91
94
  logger.warning("No channel provided %s", interaction)
92
95
  return
93
96
 
97
+ # Check bot can speak
98
+ if channel_permissions:
99
+ client_perms = discord.Permissions()
100
+ if interaction.client.user:
101
+ client_member = interaction.guild.get_member(
102
+ interaction.client.user.id
103
+ )
104
+ if client_member is not None:
105
+ client_perms = interaction.channel.permissions_for(
106
+ client_member
107
+ )
108
+ needed_channel_perms = Permissions(**channel_permissions)
109
+ if not client_perms.is_superset(needed_channel_perms):
110
+ logger.warning(
111
+ "%s failed for wrong channel permissions", event_repr
112
+ )
113
+ await interaction.response.send_message(
114
+ "Le bot n'a pas la permission",
115
+ ephemeral=True,
116
+ )
117
+ return
118
+
94
119
  # Compute needed permissions
95
120
  needed_perms = discord.Permissions(**perms)
96
121
  have_perms = interaction.user.guild_permissions.is_superset(
@@ -9,7 +9,8 @@ from .base import Context, controlled_command, egg_command_group
9
9
 
10
10
 
11
11
  @egg_command_group.command(
12
- name="disable", description="Désactiver la chasse aux œufs dans le salon"
12
+ name="disable",
13
+ description="Désactiver la chasse aux œufs dans le salon"
13
14
  )
14
15
  @controlled_command(cooldown=True, manage_channels=True)
15
16
  async def disable_command(ctx: Context) -> None:
@@ -13,7 +13,8 @@ from .base import Context, controlled_command, egg_command_group
13
13
 
14
14
 
15
15
  @egg_command_group.command(
16
- name="edit", description="Editer le nombre d'œufs d'un membre"
16
+ name="edit",
17
+ description="Editer le nombre d'œufs d'un membre",
17
18
  )
18
19
  @controlled_command(cooldown=True, administrator=True)
19
20
  async def edit_command(
@@ -9,9 +9,14 @@ from .base import Context, controlled_command, egg_command_group
9
9
 
10
10
 
11
11
  @egg_command_group.command(
12
- name="enable", description="Activer la chasse dans le salon"
12
+ name="enable",
13
+ description="Activer la chasse dans le salon"
14
+ )
15
+ @controlled_command(
16
+ cooldown=True,
17
+ channel_permissions={"send_messages": True},
18
+ manage_channels=True,
13
19
  )
14
- @controlled_command(cooldown=True, manage_channels=True)
15
20
  async def enable_command(
16
21
  ctx: Context,
17
22
  ) -> None:
@@ -148,9 +148,10 @@ async def game_dual( # noqa: C901, D103, PLR0912
148
148
 
149
149
 
150
150
  @egg_command_group.command(
151
- name="connect4", description="Lancer une partie de puissance 4."
151
+ name="connect4",
152
+ description="Lancer une partie de puissance 4"
152
153
  )
153
- @controlled_command(cooldown=True)
154
+ @controlled_command(cooldown=True, channel_permissions={"send_messages": True})
154
155
  async def connect4_command(
155
156
  ctx: Context,
156
157
  member: Optional[discord.Member] = None,
@@ -161,7 +162,8 @@ async def connect4_command(
161
162
 
162
163
 
163
164
  @egg_command_group.command(
164
- name="tictactoe", description="Lancer une partie de morpion."
165
+ name="tictactoe",
166
+ description="Lancer une partie de morpion"
165
167
  )
166
168
  @controlled_command(cooldown=True)
167
169
  async def tictactoe_command(
@@ -175,7 +177,7 @@ async def tictactoe_command(
175
177
 
176
178
  @egg_command_group.command(
177
179
  name="rockpaperscissor",
178
- description="Lancer une partie de pierre papier ciseaux.",
180
+ description="Lancer une partie de pierre papier ciseaux",
179
181
  )
180
182
  @controlled_command(cooldown=True)
181
183
  async def rockpaperscissor_command(
@@ -7,7 +7,10 @@ from easterobot.hunts.hunt import embed
7
7
  from .base import Context, controlled_command, egg_command_group
8
8
 
9
9
 
10
- @egg_command_group.command(name="help", description="Obtenir de l'aide")
10
+ @egg_command_group.command(
11
+ name="help",
12
+ description="Obtenir l'aide des commandes"
13
+ )
11
14
  @controlled_command(cooldown=True)
12
15
  async def help_command(ctx: Context) -> None:
13
16
  """Help command."""
@@ -14,7 +14,8 @@ from .base import Context, Interaction, controlled_command, egg_command_group
14
14
 
15
15
 
16
16
  @egg_command_group.command(
17
- name="reset", description="Réinitialiser la chasse aux œufs"
17
+ name="reset",
18
+ description="Réinitialiser la chasse aux œufs"
18
19
  )
19
20
  @controlled_command(cooldown=True, administrator=True)
20
21
  async def reset_command(ctx: Context) -> None:
@@ -21,8 +21,11 @@ from .base import (
21
21
  logger = logging.getLogger("easterobot")
22
22
 
23
23
 
24
- @egg_command_group.command(name="search", description="Rechercher un œuf")
25
- @controlled_command(cooldown=True)
24
+ @egg_command_group.command(
25
+ name="search",
26
+ description="Rechercher un œuf"
27
+ )
28
+ @controlled_command(cooldown=True, channel_permissions={"send_messages": True})
26
29
  async def search_command(ctx: Context) -> None:
27
30
  """Search command."""
28
31
  async with AsyncSession(ctx.client.engine) as session:
easterobot/config.py CHANGED
@@ -30,7 +30,7 @@ V = TypeVar("V")
30
30
  Members = Union[discord.Member, list[discord.Member]]
31
31
 
32
32
  HERE = pathlib.Path(__file__).parent.resolve()
33
- RESOURCES = pathlib.Path(__file__).parent.resolve() / "resources"
33
+ RESOURCES = HERE / "resources"
34
34
  DEFAULT_CONFIG_PATH = pathlib.Path("config.yml")
35
35
  EXAMPLE_CONFIG_PATH = RESOURCES / "config.example.yml"
36
36
 
@@ -166,7 +166,7 @@ class RockPaperScissor(Game):
166
166
  if not self.timeout:
167
167
  await self.set_winner(final_winner)
168
168
  else:
169
- dt = self.start_timer(63)
169
+ dt = self.start_timer(32)
170
170
  embed.description += f"\n\n{info}\n\nFin du tour {dt}"
171
171
  embed.set_author(name=header, icon_url=icon_url)
172
172
  await self.message.edit(embed=embed, view=self.view, content="")
@@ -85,7 +85,7 @@ class TicTacToe(Game):
85
85
  content += footer
86
86
 
87
87
  if not self.terminate:
88
- now = datetime.datetime.now() + datetime.timedelta(seconds=62) # noqa: DTZ005
88
+ now = datetime.datetime.now() + datetime.timedelta(seconds=32) # noqa: DTZ005
89
89
  content += f"\n\nFin du tour {format_dt(now, style='R')}"
90
90
 
91
91
  embed = discord.Embed(description=content, color=self.color(user))
@@ -142,7 +142,7 @@ class TicTacToe(Game):
142
142
  await self.set_winner(None)
143
143
  else:
144
144
  self.turn += 1
145
- self.start_timer(60)
145
+ self.start_timer(30)
146
146
  await self.update()
147
147
 
148
148
  @override
@@ -13,8 +13,8 @@ hunt:
13
13
  timeout: 300.0
14
14
  game: 0.6
15
15
  cooldown:
16
- min: 1200.0
17
- max: 3000.0
16
+ min: 600.0
17
+ max: 1800.0
18
18
  weights:
19
19
  base: 0.3
20
20
  egg: 0.4
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: easterobot
3
- Version: 1.1.0
3
+ Version: 1.1.2
4
4
  Summary: Discord bot for Easter.
5
5
  Project-URL: Homepage, https://github.com/Dashstrom/easterobot
6
6
  Project-URL: Repository, https://github.com/Dashstrom/easterobot
@@ -121,6 +121,11 @@ from `PyPI <https://pypi.org/project>`_
121
121
  cd easterobot
122
122
  echo "DISCORD_TOKEN=YOU_MUST_PUT_YOUR_TOKEN_HERE" > .env
123
123
 
124
+ # Can be unsafe
125
+ chmod -R 700 .
126
+ mkdir data
127
+ chmod 777 data
128
+
124
129
  # Run the docker container
125
130
  docker compose up -d
126
131
 
@@ -2,7 +2,7 @@ easterobot/__init__.py,sha256=jicWnRlHiIKXyAoQhL0_ga8PwMpwr_S2s33olHYoHg0,287
2
2
  easterobot/__main__.py,sha256=ix1OVjR-jxJIHzQiKyIswvn0oNphNNL9p7FtbZj9Stw,140
3
3
  easterobot/bot.py,sha256=zDijoiO-PyrIHcpypuDDx9SXNQMvIq8N1y3VvJdDbnY,6594
4
4
  easterobot/cli.py,sha256=G746r3abX-Vtcq9Ju-51FcZRj9y9PmGlIp9ADecajM4,5296
5
- easterobot/config.py,sha256=jlV1oMRPVek4jJTiOYkrLUcR5FEESxDNUv-IVmsPSoo,13095
5
+ easterobot/config.py,sha256=YAtGXyu4Emk6kuoEbO0la2xuLVsWdtcJoyPn6PJ0q2w,13060
6
6
  easterobot/info.py,sha256=q7feubgPyAaMb7D90jg9lLmGv78etpOKoumdMwEI2ek,546
7
7
  easterobot/logger.py,sha256=eUUdMB0ebvb5h98WWZka2ntivBOmfHqhlvyr-82NKn4,482
8
8
  easterobot/models.py,sha256=nFxz3S0YJAa0PuhRqoKt0ZToieFlXtHygIz3vrQ370c,1785
@@ -12,26 +12,26 @@ easterobot/alembic/script.py.mako,sha256=3qBrHBf7F7ChKDUIdiNItiSXrDpgQdM7sR0YKzp
12
12
  easterobot/alembic/versions/2f0d4305e320_init_database.py,sha256=Y8pkYG_8i3jymbTxg5ANaaShpadPo5J2TUp2ZSKxffM,2245
13
13
  easterobot/alembic/versions/940c3b9c702d_add_lock_on_eggs.py,sha256=lGGjeXzrHgRAP-i4kfMh6841EcOr3y8D1PRWaMV7ozA,943
14
14
  easterobot/commands/__init__.py,sha256=vzVx4DrveAKl4c71VRMvQjzrWzuWmayAkd0f4k7JNt4,1026
15
- easterobot/commands/base.py,sha256=j2OdmwnSphkDJUNF6ArNn3I8BqwK4Sn7IuCDDtH1yFw,5906
15
+ easterobot/commands/base.py,sha256=_P6xsre6gDdS4h2-DXfhpLBgYW774eHOSc0p6iLv7iY,7054
16
16
  easterobot/commands/basket.py,sha256=sV6JfPxg4U98dTTA5tr1wnMVM5DI9UXGL6FWL9OphTw,2924
17
- easterobot/commands/disable.py,sha256=qjgLRQZUXK9toq-vJdE6qOYX5Pxb9wjIyvWrKJ22GAo,970
18
- easterobot/commands/edit.py,sha256=QfQJoLKl3ox6evA4D_Bt8BMqT_M5w5b7z7-Rk9JXIK8,2134
19
- easterobot/commands/enable.py,sha256=IRIwIHgZS3kz60CCfQBR8sBRs25CEyvxYewsTW--TrI,1034
20
- easterobot/commands/game.py,sha256=5idVI7WOsBlYCWXYGPtwRC6rVX5PuaKrIoqrvhFFWTs,5996
21
- easterobot/commands/help.py,sha256=KquNRRgUStMuu4w26icYgSF4K-HJNLl96ZNbEg3as3U,1082
22
- easterobot/commands/reset.py,sha256=B_dTUawmXWBgbJkAyYYkyw_QjAvqvPoGTXLzUtLFPAc,3748
23
- easterobot/commands/search.py,sha256=WE7w18vPNDlWgpoj-RIZZZqGBMLjvQoygex79iPFZJU,4345
17
+ easterobot/commands/disable.py,sha256=Mm3ISPo_Vi9ALkJeQiZ3cTMm3D5qamfyMAGkoywZpac,974
18
+ easterobot/commands/edit.py,sha256=jppdU6A62zhWaO_LFukbp2eTSyiL9NKyK7fBI9n1Ph8,2139
19
+ easterobot/commands/enable.py,sha256=dIvvm7zLJ1nDbO8YaCG6C2DfAUdDb3TtbDK4pFq6VeU,1098
20
+ easterobot/commands/game.py,sha256=-UuUZgsVhDB7C1LINlOaO4lyuUN8Zn-m2tFXFwwCqyo,6046
21
+ easterobot/commands/help.py,sha256=hmhc7ybEOlmdtAojanQhlUyImjHJFKddKCypAYC_ZvA,1103
22
+ easterobot/commands/reset.py,sha256=n--TDZmlRdlKDxeCKaPZGPnJ46AwS4mevP_l4haIVxM,3752
23
+ easterobot/commands/search.py,sha256=ZV9SqC1uMD-JR5Si8_DJXWM597uoRLsWeCUeT3Irz_E,4400
24
24
  easterobot/commands/top.py,sha256=qjtRtvBKeKq228nRm_RYLY8HMrnz3n_fteBlr4WCpG0,3017
25
25
  easterobot/games/__init__.py,sha256=WHqTEE4OW1kwOZlzQslkXYMf38nDX5gT01zsgDAr80g,259
26
26
  easterobot/games/connect.py,sha256=tEwYv5nuSF_wbc4wqhizYnX5LcLwygylAskD7604kZo,6397
27
27
  easterobot/games/game.py,sha256=M5OF4hvnblmlUM1z_VdehRENl9k08eJmM0WU-65zsjg,8942
28
- easterobot/games/rock_paper_scissor.py,sha256=eDbdrVFuftDunvAQPU3Av41AGHmg6nwfltX8KANw1Hg,7091
29
- easterobot/games/tic_tac_toe.py,sha256=ob1uaC4swpoB1gOAzweuALZNmhEfocprL9GQVVdpjKk,5115
28
+ easterobot/games/rock_paper_scissor.py,sha256=nIJySpbVQd-4gXXPFxW3cxQhNBzSgS1HiI-Pm1uTRZ0,7091
29
+ easterobot/games/tic_tac_toe.py,sha256=vHJcrwgC0SmWOsRqPxi_wR-p3_99Tgi-fMg7J-eSKfg,5115
30
30
  easterobot/hunts/__init__.py,sha256=R0fO04m1F9kEmBy_5EzlYvWVjmY74q5adINEZGGnwCQ,258
31
31
  easterobot/hunts/hunt.py,sha256=KS6wHOdMXirPJQUPwEt7NHyngWxJfAjf0tHVujtu0k0,14844
32
32
  easterobot/hunts/rank.py,sha256=EYvyXfYqklvMflJJfcByYHhaU_NKq_D10aqOl7XuF8E,2274
33
33
  easterobot/resources/alembic.ini,sha256=SmGkhRx5iZMpjEa5avCfz1lpF0_WZPEbGA_6MSI1GjU,3297
34
- easterobot/resources/config.example.yml,sha256=6kUiraJZm7epWe_B2_M6Ppc08knIaPn1a-avcpOlG_4,15739
34
+ easterobot/resources/config.example.yml,sha256=SKKh57J9OrRlsyRkLVMglr7R4WnnShfqAP6fx7gafDc,15738
35
35
  easterobot/resources/credits.txt,sha256=zJT_OmCi_PqBPQnWPvWWI9sJx6hPrXcDnNNpLRWDd20,378
36
36
  easterobot/resources/logging.conf,sha256=RSL4k79N5oQb1hEtr5SiR_IAiKjkAHZaR4DR9lOxA-M,838
37
37
  easterobot/resources/logo.png,sha256=DUFH6Tq8MjW0LGWVc4sox6RvBZCQWHZHTM2e5Ua4od4,82599
@@ -59,8 +59,8 @@ easterobot/resources/emotes/icons/arrow.png,sha256=ZkAicY2AONJUQRTdvkG77wPO5EYE9
59
59
  easterobot/resources/emotes/icons/end.png,sha256=8jkufw0aS99tyZCb80PUzT2mkipQrYxwuFOFmOH6UNk,24526
60
60
  easterobot/resources/emotes/icons/versus.png,sha256=Ss9PZu4nENB7xo8Kdunt0STvCSrMbo-bTaYz-NJ8tfI,29212
61
61
  easterobot/resources/emotes/icons/wait.png,sha256=xXK6bKtPpD1f5wSjMGqzuPzVdV4gkOgMSJ_fVjuzJp4,20378
62
- easterobot-1.1.0.dist-info/METADATA,sha256=SAZsbRjw-Akcp2ypf7U9pVkW9FquARz7cjUAbBNxBfY,7467
63
- easterobot-1.1.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
64
- easterobot-1.1.0.dist-info/entry_points.txt,sha256=KaH17cNnu7qbWxFcMaj1wZ9GPTjWJ1OTqkBMhoLOmCQ,57
65
- easterobot-1.1.0.dist-info/licenses/LICENSE,sha256=kYRz570GVPktzhJxWtaencsrsjdKSetpe5WISlDrvnY,1093
66
- easterobot-1.1.0.dist-info/RECORD,,
62
+ easterobot-1.1.2.dist-info/METADATA,sha256=unwCPE-OZfIzv3X22f8cE7qAp8IrkopvX7DG9WRtqh8,7541
63
+ easterobot-1.1.2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
64
+ easterobot-1.1.2.dist-info/entry_points.txt,sha256=KaH17cNnu7qbWxFcMaj1wZ9GPTjWJ1OTqkBMhoLOmCQ,57
65
+ easterobot-1.1.2.dist-info/licenses/LICENSE,sha256=kYRz570GVPktzhJxWtaencsrsjdKSetpe5WISlDrvnY,1093
66
+ easterobot-1.1.2.dist-info/RECORD,,