timer-bot 1.6__tar.gz → 1.8__tar.gz

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.
@@ -1,6 +1,17 @@
1
1
  Changelog
2
2
  =========
3
3
 
4
+ 1.8 (2024-12-01)
5
+ ----------------
6
+
7
+ - Upgrade to discord-py-interactions 5.13
8
+
9
+ 1.7 (2024-02-06)
10
+ ----------------
11
+
12
+ - Fix python 3.11 install for Debian 12
13
+
14
+
4
15
  1.6 (2023-11-04)
5
16
  ----------------
6
17
 
@@ -1,28 +1,26 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: timer-bot
3
- Version: 1.6
4
- Summary: "Discord Timer Bot",
5
- Home-page: http://github.com/lionel-panhaleux/timer-bot
6
- Author: lionelpx
7
- Author-email: lionel.panhaleux@gmail.com
8
- License: "MIT"
9
- Keywords: discord game timer
10
- Classifier: Development Status :: 4 - Beta
3
+ Version: 1.8
4
+ Summary: Discord Timer Bot
5
+ Author-email: Lionel Panhaleux <lionel.panhaleux+timer@gmail.com>
6
+ Project-URL: Repository, https://github.com/lionel-panhaleux/timer-bot
7
+ Keywords: Discord,timer
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.11
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Development Status :: 5 - Production/Stable
11
12
  Classifier: Intended Audience :: Other Audience
12
13
  Classifier: Natural Language :: English
13
14
  Classifier: Operating System :: OS Independent
14
- Classifier: Environment :: Console
15
- Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.8
17
- Classifier: Topic :: Other/Nonlisted Topic
15
+ Classifier: Environment :: Web Environment
16
+ Requires-Python: >=3.11
18
17
  Description-Content-Type: text/markdown
19
18
  License-File: LICENSE
20
- Requires-Dist: discord-py-interactions>=4.4.1
19
+ Requires-Dist: discord-py-interactions>5.13
20
+ Requires-Dist: uvloop>0.21
21
21
  Provides-Extra: dev
22
22
  Requires-Dist: black; extra == "dev"
23
- Requires-Dist: doc8; extra == "dev"
24
- Requires-Dist: flake8; extra == "dev"
25
- Requires-Dist: pytest; extra == "dev"
23
+ Requires-Dist: ruff; extra == "dev"
26
24
  Requires-Dist: zest.releaser[recommended]; extra == "dev"
27
25
 
28
26
  # timer
@@ -0,0 +1,40 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "timer-bot"
7
+ version = "1.8"
8
+ authors = [
9
+ { name = "Lionel Panhaleux", email = "lionel.panhaleux+timer@gmail.com" },
10
+ ]
11
+ description = "Discord Timer Bot"
12
+ keywords = ["Discord", "timer"]
13
+ readme = "README.md"
14
+ requires-python = ">=3.11"
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.11",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Development Status :: 5 - Production/Stable",
20
+ "Intended Audience :: Other Audience",
21
+ "Natural Language :: English",
22
+ "Operating System :: OS Independent",
23
+ "Environment :: Web Environment",
24
+ ]
25
+ dependencies = ["discord-py-interactions>5.13", "uvloop>0.21"]
26
+
27
+ [project.optional-dependencies]
28
+ dev = ["black", "ruff", "zest.releaser[recommended]"]
29
+
30
+ [project.scripts]
31
+ timer-bot = "src.timer_bot:main"
32
+
33
+ [project.urls]
34
+ Repository = "https://github.com/lionel-panhaleux/timer-bot"
35
+
36
+ [tool.setuptools.packages.find]
37
+ include = ["src*"]
38
+
39
+ [tool.zest-releaser]
40
+ create-wheel = true
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -5,19 +5,35 @@ import os
5
5
 
6
6
  import interactions
7
7
 
8
+ import interactions.api.events
9
+ import interactions.client.errors
10
+
8
11
 
9
12
  logger = logging.getLogger()
10
13
  bot = interactions.Client(
11
14
  token=os.getenv("DISCORD_TOKEN") or "",
12
- intents=interactions.Intents.DEFAULT,
15
+ # intents=interactions.Intents.new(guild_messages=True),
16
+ delete_unused_application_cmds=True,
17
+ debug_scope=161406117686149120 if __debug__ else interactions.MISSING,
18
+ logging_level=logging.DEBUG if __debug__ else logging.INFO,
13
19
  )
14
- TIMERS = {}
15
20
 
16
21
 
17
- @bot.event
22
+ @interactions.listen()
18
23
  async def on_ready():
19
24
  """Login success"""
20
- logger.info(f"Logged in as {bot.me.name}")
25
+ logger.info(f"Logged in as {bot.user.username}")
26
+
27
+
28
+ @interactions.listen()
29
+ async def on_startup():
30
+ """Startup success"""
31
+ logger.info(f"Started")
32
+
33
+
34
+ @interactions.listen()
35
+ async def on_error(error: interactions.api.events.Error):
36
+ logger.error("API error: %s", error)
21
37
 
22
38
 
23
39
  #: fixed list of times on which to send a notification
@@ -49,39 +65,47 @@ RUNNING_TIMER_HELP = (
49
65
  class Timer:
50
66
  """Timer object: one per channel"""
51
67
 
52
- def __init__(self, channel, author, time, secured, log_prefix=""):
68
+ def __init__(
69
+ self,
70
+ channel: interactions.GuildChannel,
71
+ author: interactions.Member,
72
+ time: int,
73
+ secured: bool,
74
+ log_prefix: str = "",
75
+ ):
53
76
  self.channel = channel
54
77
  self.author = author
55
78
  self.secured = secured
56
- self.start_time = 0
57
- self.total_time = time
58
- self.time_left = time
79
+ self.start_time: float = 0
80
+ self.total_time: int = 0
81
+ self.time_left: float = 0
59
82
  self.log_prefix = log_prefix + "|internal"
60
- self.thresholds = []
61
- for limit in THRESHOLDS:
62
- if time > limit:
63
- self.thresholds.append(limit)
64
- # add a threshold on every hour
65
- for limit in range(1, time // 3600 + 1):
66
- self.thresholds.append(limit * 3600)
83
+ self.thresholds: list[int] = []
84
+ self.adjust_time(time)
67
85
  # internals
68
86
  self.message: Optional[interactions.Message] = None
69
87
  self.countdown_future = None # waiting for time to refresh
70
88
  self.resume_future = None # waiting for resume
71
89
 
90
+ def adjust_time(self, time: int):
91
+ self.total_time += time
92
+ self.time_left += time
93
+ self.thresholds = [limit for limit in THRESHOLDS if self.time_left > limit]
94
+ # add a threshold on every hour
95
+ for limit in range(1, int(self.time_left // 3600) + 1):
96
+ self.thresholds.append(limit * 3600)
97
+
72
98
  async def countdown(self):
73
99
  """Countdown: update embed, send notifications"""
74
100
  while self.time_left > 0:
75
101
  # update time_left
76
102
  if not self.resume_future:
77
- self.time_left = max(
78
- 0,
79
- self.total_time - max(0, bot._loop.time() - self.start_time),
80
- )
103
+ time_spent = max(0, asyncio.get_event_loop().time() - self.start_time)
104
+ self.time_left = max(0, self.total_time - time_spent)
81
105
  await self._send_or_update_message()
82
106
  # update frequency depends on time left
83
107
  if self.resume_future:
84
- paused_time = bot._loop.time()
108
+ paused_time = asyncio.get_event_loop().time()
85
109
  try:
86
110
  logging.debug(f"[{self.log_prefix}] Wait for resume")
87
111
  await self.resume_future
@@ -92,7 +116,7 @@ class Timer:
92
116
  finally: # in any case resume.
93
117
  logging.debug(f"[{self.log_prefix}] Timer resume")
94
118
  self.resume_future = None
95
- self.start_time += bot._loop.time() - paused_time
119
+ self.start_time += asyncio.get_event_loop().time() - paused_time
96
120
  else:
97
121
  if self.time_left < DISPLAY_SECONDS + 30:
98
122
  # minimum because of Discord rate limitation
@@ -113,7 +137,7 @@ class Timer:
113
137
  """Run the timer, update the client.TIMERS map accordingly."""
114
138
  logging.debug(f"[{self.log_prefix}] Run")
115
139
  TIMERS[self.channel] = self
116
- self.start_time = bot._loop.time()
140
+ self.start_time = asyncio.get_event_loop().time()
117
141
  try:
118
142
  await self.countdown()
119
143
  except asyncio.CancelledError:
@@ -191,17 +215,22 @@ class Timer:
191
215
  embeds = [interactions.Embed(title=title, description=description)]
192
216
  if self.message:
193
217
  try:
194
- await self.message.edit(embeds=embeds, components=components)
218
+ self.message = await self.message.edit(
219
+ embeds=embeds, components=components
220
+ )
195
221
  # messages older than 1h cannot be edited too much, at some point it fails
196
- except interactions.LibraryException as e:
222
+ except interactions.errors.LibraryException as e:
223
+ logger.info("Failed to edit message: %s", e)
197
224
  old_message = self.message
198
225
  self.message = await self.channel.send(
199
226
  embeds=embeds, components=components
200
227
  )
201
- try:
202
- await old_message.delete()
203
- except interactions.LibraryException:
204
- pass
228
+ if old_message:
229
+ try:
230
+ await old_message.delete()
231
+ except interactions.errors.LibraryException as e:
232
+ logger.info("Failed to delete old message: %s", e)
233
+ pass
205
234
  else:
206
235
  self.message = await self.channel.send(embeds=embeds, components=components)
207
236
  if self.thresholds and self.thresholds[-1] >= self.time_left >= 0:
@@ -234,29 +263,15 @@ class Timer:
234
263
  return "time!"
235
264
 
236
265
 
237
- @bot.event(name="on_message_create")
238
- async def on_message_create(message: interactions.Message):
239
- """Main message loop"""
240
- if message.author.id == bot.me.id:
241
- return
242
-
243
- if message.content.lower().startswith("timer "):
244
- await message.reply(
245
- "This bot switched to slash commands. Use `/timer` instead."
246
- )
247
-
266
+ TIMERS: dict[interactions.Snowflake : Timer] = {}
267
+ timer_base = interactions.SlashCommand(name="timer")
248
268
 
249
- @bot.command(name="timer")
250
- async def base_timer_command(ctx: interactions.CommandContext):
251
- pass
252
269
 
253
-
254
- def _get_prefix(ctx: interactions.CommandContext):
270
+ def _get_prefix(ctx: interactions.SlashContext):
255
271
  """Prefix used for log messages"""
256
272
  if ctx.guild:
257
273
  prefix = f"{ctx.guild.name}"
258
274
  logger.debug("CTX: %s", ctx)
259
- logger.debug("extras: %s", ctx._extras)
260
275
  logger.debug("channel: %s", ctx.channel)
261
276
  logger.debug("channel_id: %s", ctx.channel_id)
262
277
  if ctx.channel:
@@ -266,36 +281,34 @@ def _get_prefix(ctx: interactions.CommandContext):
266
281
  return prefix
267
282
 
268
283
 
269
- @base_timer_command.subcommand(
270
- name="start",
271
- description="Start a timer",
272
- options=[
273
- interactions.Option(
274
- name="hours",
275
- description="Number of hours",
276
- type=interactions.OptionType.INTEGER,
277
- required=True,
278
- min_value=0,
279
- max_value=24,
280
- ),
281
- interactions.Option(
282
- name="minutes",
283
- description="Number of minutes",
284
- type=interactions.OptionType.INTEGER,
285
- required=False,
286
- min_value=0,
287
- max_value=59,
288
- ),
289
- interactions.Option(
290
- name="secured",
291
- description="Only the owner can modify a secure timer (default false)",
292
- type=interactions.OptionType.BOOLEAN,
293
- required=False,
294
- ),
295
- ],
284
+ @timer_base.subcommand(
285
+ sub_cmd_name="start",
286
+ sub_cmd_description="Start a timer",
287
+ )
288
+ @interactions.slash_option(
289
+ name="hours",
290
+ opt_type=interactions.OptionType.INTEGER,
291
+ description="Number of hours",
292
+ required=True,
293
+ min_value=0,
294
+ max_value=24,
295
+ )
296
+ @interactions.slash_option(
297
+ name="minutes",
298
+ opt_type=interactions.OptionType.INTEGER,
299
+ description="Number of minutes",
300
+ required=False,
301
+ min_value=0,
302
+ max_value=59,
303
+ )
304
+ @interactions.slash_option(
305
+ name="secured",
306
+ opt_type=interactions.OptionType.BOOLEAN,
307
+ description="Only the owner can modify a secure timer (default false)",
308
+ required=False,
296
309
  )
297
310
  async def timer_start(
298
- ctx: interactions.CommandContext,
311
+ ctx: interactions.SlashContext,
299
312
  hours: int,
300
313
  minutes: int = 0,
301
314
  secured: bool = False,
@@ -304,9 +317,7 @@ async def timer_start(
304
317
  # channel info will miss from threads and voice channels chats
305
318
  # see https://github.com/interactions-py/library/issues/1041
306
319
  if ctx.channel is interactions.MISSING:
307
- ctx.channel = interactions.Channel(
308
- _client=ctx.client, **(await ctx.client.get_channel(ctx.channel_id))
309
- )
320
+ ctx.channel = await ctx.client.get_channel(ctx.channel_id)
310
321
  prefix = _get_prefix(ctx)
311
322
  # timer already running in channel
312
323
  if ctx.channel_id in TIMERS:
@@ -327,7 +338,7 @@ async def timer_start(
327
338
  logger.info(f"[{prefix}] Start timer: {hours}h {minutes}min")
328
339
  try:
329
340
  await timer.run()
330
- except interactions.LibraryException:
341
+ except interactions.client.errors.LibraryException:
331
342
  await ctx.edit(
332
343
  "**Failed to start**\nTimer bot requires permission to send messages"
333
344
  )
@@ -344,39 +355,37 @@ async def timer_start(
344
355
  )
345
356
 
346
357
 
347
- @base_timer_command.subcommand(name="pause", description="pause the timer")
348
- async def timer_pause(ctx: interactions.CommandContext):
358
+ @timer_base.subcommand(sub_cmd_name="pause", sub_cmd_description="pause the timer")
359
+ async def timer_pause(ctx: interactions.SlashContext):
349
360
  """Pause the timer"""
350
361
  await _pause_timer(ctx)
351
362
 
352
363
 
353
- @base_timer_command.subcommand(name="resume", description="resume the timer")
354
- async def timer_resume(ctx: interactions.CommandContext):
364
+ @timer_base.subcommand(sub_cmd_name="resume", sub_cmd_description="resume the timer")
365
+ async def timer_resume(ctx: interactions.SlashContext):
355
366
  """Resume the timer"""
356
367
  await _resume_timer(ctx)
357
368
 
358
369
 
359
- @base_timer_command.subcommand(name="stop", description="stop the timer")
360
- async def timer_stop(ctx: interactions.CommandContext):
370
+ @timer_base.subcommand(sub_cmd_name="stop", sub_cmd_description="stop the timer")
371
+ async def timer_stop(ctx: interactions.SlashContext):
361
372
  """Stop the timer"""
362
373
  await _stop_timer(ctx)
363
374
 
364
375
 
365
- @base_timer_command.subcommand(
366
- name="add",
367
- description="Add time",
368
- options=[
369
- interactions.Option(
370
- name="minutes",
371
- description="Number of minutes",
372
- type=interactions.OptionType.INTEGER,
373
- required=True,
374
- min_value=1,
375
- max_value=1440,
376
- ),
377
- ],
376
+ @timer_base.subcommand(
377
+ sub_cmd_name="add",
378
+ sub_cmd_description="Add time",
378
379
  )
379
- async def timer_add(ctx: interactions.CommandContext, minutes: int):
380
+ @interactions.slash_option(
381
+ name="minutes",
382
+ opt_type=interactions.OptionType.INTEGER,
383
+ description="Number of minutes",
384
+ required=True,
385
+ min_value=1,
386
+ max_value=1440,
387
+ )
388
+ async def timer_add(ctx: interactions.SlashContext, minutes: int):
380
389
  """Add time to the timer"""
381
390
  timer = TIMERS.get(ctx.channel, None)
382
391
  if not timer:
@@ -391,29 +400,25 @@ async def timer_add(ctx: interactions.CommandContext, minutes: int):
391
400
  "This is a secured timer, only the owner can modify it.", ephemeral=True
392
401
  )
393
402
  return
394
- time = minutes * 60
395
- timer.total_time += time
396
- timer.time_left += time
403
+ timer.adjust_time(minutes * 60)
397
404
  await timer.refresh(resume=False)
398
- logger.info(f"[{prefix}] Added {time//60}min and refreshed")
405
+ logger.info(f"[{prefix}] Added {minutes}min and refreshed")
399
406
  await ctx.send(f"Time added ({minutes}min)")
400
407
 
401
408
 
402
- @base_timer_command.subcommand(
403
- name="sub",
404
- description="Substract time",
405
- options=[
406
- interactions.Option(
407
- name="minutes",
408
- description="Number of minutes",
409
- type=interactions.OptionType.INTEGER,
410
- required=True,
411
- min_value=1,
412
- max_value=1440,
413
- ),
414
- ],
409
+ @timer_base.subcommand(
410
+ sub_cmd_name="sub",
411
+ sub_cmd_description="Substract time",
412
+ )
413
+ @interactions.slash_option(
414
+ name="minutes",
415
+ opt_type=interactions.OptionType.INTEGER,
416
+ description="Number of minutes",
417
+ required=True,
418
+ min_value=1,
419
+ max_value=1440,
415
420
  )
416
- async def timer_sub(ctx: interactions.CommandContext, minutes: int):
421
+ async def timer_sub(ctx: interactions.SlashContext, minutes: int):
417
422
  """Substract time from the timer"""
418
423
  timer = TIMERS.get(ctx.channel, None)
419
424
  if not timer:
@@ -428,16 +433,16 @@ async def timer_sub(ctx: interactions.CommandContext, minutes: int):
428
433
  "This is a secured timer, only the owner can modify it.", ephemeral=True
429
434
  )
430
435
  return
431
- time = minutes * 60
432
- timer.total_time -= time
433
- timer.time_left -= time
436
+ timer.adjust_time(-minutes * 60)
434
437
  await timer.refresh(resume=False)
435
- logger.info(f"[{prefix}] Substracted {time//60}min and refreshed")
438
+ logger.info(f"[{prefix}] Substracted {minutes}min and refreshed")
436
439
  await ctx.send(f"Time substracted ({minutes}min)")
437
440
 
438
441
 
439
- @base_timer_command.subcommand(name="display", description="Display the timer anew")
440
- async def timer_display(ctx: interactions.CommandContext):
442
+ @timer_base.subcommand(
443
+ sub_cmd_name="display", sub_cmd_description="Display the timer anew"
444
+ )
445
+ async def timer_display(ctx: interactions.SlashContext):
441
446
  """Discplay the timer anew"""
442
447
  timer = TIMERS.get(ctx.channel, None)
443
448
  if not timer:
@@ -456,41 +461,41 @@ button_pause = interactions.Button(
456
461
  style=interactions.ButtonStyle.PRIMARY,
457
462
  label="Pause",
458
463
  custom_id="pause",
459
- emoji=interactions.Emoji(name="⏱"),
464
+ emoji=interactions.PartialEmoji.from_str("⏱"),
460
465
  )
461
466
 
462
467
  button_resume = interactions.Button(
463
468
  style=interactions.ButtonStyle.SUCCESS,
464
469
  label="Resume",
465
470
  custom_id="resume",
466
- emoji=interactions.Emoji(name="▶️"),
471
+ emoji=interactions.PartialEmoji.from_str("▶️"),
467
472
  )
468
473
 
469
474
  button_stop = interactions.Button(
470
475
  style=interactions.ButtonStyle.DANGER,
471
476
  label="Stop",
472
477
  custom_id="stop",
473
- emoji=interactions.Emoji(name="🛑"),
478
+ emoji=interactions.PartialEmoji.from_str("🛑"),
474
479
  )
475
480
 
476
481
 
477
- @bot.component("pause")
482
+ @interactions.component_callback("pause")
478
483
  async def button_pause_response(ctx: interactions.ComponentContext):
479
484
  await _pause_timer(ctx)
480
485
 
481
486
 
482
- @bot.component("resume")
487
+ @interactions.component_callback("resume")
483
488
  async def button_resume_response(ctx: interactions.ComponentContext):
484
489
  await _resume_timer(ctx)
485
490
 
486
491
 
487
- @bot.component("stop")
492
+ @interactions.component_callback("stop")
488
493
  async def button_stop_response(ctx: interactions.ComponentContext):
489
494
  await _stop_timer(ctx)
490
495
 
491
496
 
492
497
  async def _pause_timer(
493
- ctx: Union[interactions.CommandContext, interactions.ComponentContext]
498
+ ctx: Union[interactions.SlashContext, interactions.ComponentContext]
494
499
  ):
495
500
  timer = TIMERS.get(ctx.channel, None)
496
501
  if not timer:
@@ -517,7 +522,7 @@ async def _pause_timer(
517
522
 
518
523
 
519
524
  async def _resume_timer(
520
- ctx: Union[interactions.CommandContext, interactions.ComponentContext]
525
+ ctx: Union[interactions.SlashContext, interactions.ComponentContext]
521
526
  ):
522
527
  timer = TIMERS.get(ctx.channel, None)
523
528
  if not timer:
@@ -538,7 +543,7 @@ async def _resume_timer(
538
543
 
539
544
 
540
545
  async def _stop_timer(
541
- ctx: Union[interactions.CommandContext, interactions.ComponentContext]
546
+ ctx: Union[interactions.SlashContext, interactions.ComponentContext]
542
547
  ):
543
548
  timer = TIMERS.get(ctx.channel, None)
544
549
  if not timer:
@@ -556,6 +561,20 @@ async def _stop_timer(
556
561
  await ctx.send("Timer stopped", ephemeral=True)
557
562
 
558
563
 
564
+ bot.add_listener(on_ready)
565
+ bot.add_listener(on_startup)
566
+ bot.add_command(timer_start)
567
+ bot.add_command(timer_stop)
568
+ bot.add_command(timer_pause)
569
+ bot.add_command(timer_resume)
570
+ bot.add_command(timer_display)
571
+ bot.add_command(timer_add)
572
+ bot.add_command(timer_sub)
573
+ bot.add_component_callback(button_pause_response)
574
+ bot.add_component_callback(button_resume_response)
575
+ bot.add_component_callback(button_stop_response)
576
+
577
+
559
578
  def main():
560
579
  """Entrypoint"""
561
580
  logger.addHandler(logging.StreamHandler())
@@ -2,7 +2,6 @@ CHANGELOG.rst
2
2
  LICENSE
3
3
  MANIFEST.in
4
4
  README.md
5
- setup.cfg
6
- setup.py
5
+ pyproject.toml
7
6
  src/__init__.py
8
7
  src/timer_bot.py
timer-bot-1.6/setup.cfg DELETED
@@ -1,68 +0,0 @@
1
- [metadata]
2
- name = timer-bot
3
- version = 1.6
4
- author = lionelpx
5
- author_email = lionel.panhaleux@gmail.com
6
- url = http://github.com/lionel-panhaleux/timer-bot
7
- description = "Discord Timer Bot",
8
- long_description = file: README.md
9
- long_description_content_type = text/markdown
10
- license = "MIT"
11
- keywords = discord game timer
12
- classifiers =
13
- Development Status :: 4 - Beta
14
- Intended Audience :: Other Audience
15
- Natural Language :: English
16
- Operating System :: OS Independent
17
- Environment :: Console
18
- Programming Language :: Python :: 3
19
- Programming Language :: Python :: 3.8
20
- Topic :: Other/Nonlisted Topic
21
-
22
- [options]
23
- zip_safe = True
24
- include_package_data = True
25
- packages = find:
26
- setup_requires =
27
- setuptools
28
- install_requires =
29
- discord-py-interactions>=4.4.1
30
-
31
- [options.entry_points]
32
- console_scripts =
33
- timer-bot = src.timer_bot:main
34
-
35
- [options.extras_require]
36
- dev =
37
- black
38
- doc8
39
- flake8
40
- pytest
41
- zest.releaser[recommended]
42
-
43
- [options.packages.find]
44
- exclude =
45
- tests
46
-
47
- [flake8]
48
- max-line-length = 88
49
- exclude = build, dist
50
- ignore = E203, W503
51
-
52
- [bdist_wheel]
53
- python-tag = py3
54
-
55
- [distutils]
56
- index-servers = pypi
57
-
58
- [tool:pytest]
59
- filterwarnings =
60
- ignore:.*format string will parse more strictly.*:DeprecationWarning
61
-
62
- [zest.releaser]
63
- create-wheel = yes
64
-
65
- [egg_info]
66
- tag_build =
67
- tag_date = 0
68
-
timer-bot-1.6/setup.py DELETED
@@ -1,4 +0,0 @@
1
- import setuptools
2
-
3
-
4
- setuptools.setup()
File without changes
File without changes
File without changes
File without changes