PycordViews 1.0.2__py3-none-any.whl → 1.1.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PycordViews
3
- Version: 1.0.2
3
+ Version: 1.1.1
4
4
  Summary: Views for py-cord library
5
5
  Home-page: https://github.com/BOXERRMD/Py-cord_Views
6
6
  Author: Chronos (alias BOXERRMD)
@@ -36,6 +36,7 @@ Dynamic: summary
36
36
 
37
37
  ```python
38
38
  from pycordViews.pagination import Pagination
39
+ from pycordViews.menu import SelectMenu
39
40
  import discord
40
41
 
41
42
  intents = discord.Intents.all()
@@ -57,6 +58,23 @@ async def pagination_command(ctx):
57
58
 
58
59
  await pages.respond(ctx=ctx) # respond to the command
59
60
  await pages.send(send_to=ctx.author) # send the message to the command author
60
-
61
+
62
+ @bot.command(name="My command select")
63
+ async def select_command(ctx):
64
+ """
65
+ Create a command select
66
+ """
67
+ async def your_response(select, interaction):
68
+ await interaction.response.send(f"You have selected {select.values[0]} !")
69
+
70
+ my_selector = SelectMenu(timeout=None, disabled_on_timeout=False) # A basic selector menu
71
+ my_menu = my_selector.add_string_select_menu(placeholder="Choice anything !") # add string_select UI
72
+
73
+ my_menu.add_option(label="My first choice !", emoji="😊", default=True, description="It's the first choice !", value='first choice')
74
+ my_menu.add_option(label="My second choice !", value='second choice')
75
+ my_menu.set_callable(your_response)
76
+
77
+ await my_selector.respond(ctx)
78
+
61
79
  bot.run("Your token")
62
80
  ```
@@ -0,0 +1,23 @@
1
+ pycordViews/__init__.py,sha256=SihgmXFTu75CxGmvRhVRHsRm4aDjMy8ZgiXfPuE3suE,223
2
+ pycordViews/typeViews.py,sha256=5q_-FTUGMg2QjA7bsjbb2ep41Y4sm2sBPTCOV6b5X1w,122
3
+ pycordViews/menu/__init__.py,sha256=SoAHnpJXxwTYDX5esYkgvSqpPqkuF1hDx22a-_U7ieU,83
4
+ pycordViews/menu/errors.py,sha256=0Um-oH5qMdWSZB_bGlqILsf9WSDtC4n_HwkheekiMV4,480
5
+ pycordViews/menu/menu.py,sha256=piouHpZLhHSo8MtJjx3eUp0zLzZoxj0n05pwdy0EJl4,1786
6
+ pycordViews/menu/selectMenu.py,sha256=lxgMfTFt-pEu1BRm1zqcJJgMpBWHwwuDtY4hOY4deyA,9809
7
+ pycordViews/multibot/__init__.py,sha256=fP7jipm2AfsNyMLGgh4TEhvASA7NrPSLhSl2hU_xkw4,175
8
+ pycordViews/multibot/errors.py,sha256=8C6jRRCOs3Y_tY_cvZIsGvz7XSreCkvWQ5ikj2hOf2s,238
9
+ pycordViews/multibot/process_for_bots.py,sha256=O7Drpyy_A4y1zQq2D3SXLySWLJPnz6WVdynvTPk8gKM,3920
10
+ pycordViews/multibot/process_messages.py,sha256=tt39bcfVOxTgo7_O4FPYA88spQMqx2Dvee1T2FyURmQ,108
11
+ pycordViews/multibot/runner.py,sha256=ZyHTDu-wdZFbnoyEC00qe8MTf-STqFvrXytUE8Hr-Ec,406
12
+ pycordViews/multibot/start_multibot.py,sha256=mHDBhiy7-Z3rvLbr8Ibqe9J9RXe_BusbZxq0aO3a16w,2598
13
+ pycordViews/pagination/__init__.py,sha256=Z9BcdoTWyC1KXGwQ1_C0tu9rkZpdrrjEHwMmjXsckeE,81
14
+ pycordViews/pagination/errors.py,sha256=CYb5gBcXx0kYDUDkNpfUrqSxQAcJE_qfpomWtUFOsTk,316
15
+ pycordViews/pagination/pagination_view.py,sha256=RRx4Ldr7RYp5n6-y7JttAu6fN_kD5QN9ROmuhkMCt_4,4307
16
+ pycordViews/views/__init__.py,sha256=yligptZmw-np8tjKLr76SVmi0807Nk6jCyKkKYLhbCY,89
17
+ pycordViews/views/easy_modified_view.py,sha256=umura9gYSt15z6nc5-YfRAF80ZtfmHJ88mYqdTgpxzM,8139
18
+ pycordViews/views/errors.py,sha256=0NBjBDaSFZChJua1ho9qyfbNzwXy1U6Kcob5CCUxBK8,218
19
+ PycordViews-1.1.1.dist-info/LICENSE,sha256=lNgcw1_xb7QENAQi3uHGymaFtbs0RV-ihiCd7AoLQjA,1082
20
+ PycordViews-1.1.1.dist-info/METADATA,sha256=cExBqgdH5v8HMB4-mzfrZhnphqKtaxHpU_8wv0k-IK4,2897
21
+ PycordViews-1.1.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
22
+ PycordViews-1.1.1.dist-info/top_level.txt,sha256=nqBU40KmnSCjtry8kmv97-RvZC-8xQrhrrloOJX2ROs,91
23
+ PycordViews-1.1.1.dist-info/RECORD,,
@@ -1,3 +1,5 @@
1
1
  pycordViews
2
+ pycordViews/menu
3
+ pycordViews/multibot
2
4
  pycordViews/pagination
3
5
  pycordViews/views
pycordViews/__init__.py CHANGED
@@ -1,3 +1,5 @@
1
1
  from .typeViews import *
2
2
  from .views.easy_modified_view import EasyModifiedViews
3
3
  from .pagination.pagination_view import Pagination
4
+ from .multibot.start_multibot import Multibot
5
+ from .menu.selectMenu import SelectMenu
@@ -0,0 +1,3 @@
1
+ from .selectMenu import SelectMenu
2
+ from .menu import Menu
3
+ from .errors import *
@@ -0,0 +1,17 @@
1
+ from typing import Any
2
+ class MenuError(Exception):
3
+ pass
4
+
5
+ class NotCoroutineError(MenuError):
6
+ def __init__(self, callable: Any):
7
+ """
8
+ If callable is not a coroutine
9
+ """
10
+ super().__init__(f"{callable} is not a coroutine")
11
+
12
+ class ComponentTypeError(MenuError):
13
+ def __init__(self):
14
+ """
15
+ If the component type is not a string_select
16
+ """
17
+ super().__init__(f"Only string select type is available")
@@ -0,0 +1,57 @@
1
+ from discord.components import ComponentType
2
+ from discord.ui import Select
3
+ from discord import MISSING, Emoji, PartialEmoji
4
+ from typing import Callable, Union
5
+
6
+ from .errors import NotCoroutineError, ComponentTypeError
7
+
8
+
9
+ class Menu:
10
+
11
+ def __init__(self, menu_type: ComponentType, selectmenu: "SelectMenu", **kwargs):
12
+ """
13
+ A basic menu from selectMenu class
14
+ """
15
+ self.__menu: Select = Select(select_type=menu_type, **kwargs)
16
+ self.__selectMenu = selectmenu
17
+
18
+ def set_callable(self, _callable: Callable) -> "Menu":
19
+ """
20
+ Add a coroutine to the menu
21
+ """
22
+ if not isinstance(_callable, Callable):
23
+ raise NotCoroutineError(_callable)
24
+
25
+ self.__selectMenu.set_callable(self.__menu.custom_id, _callable=_callable)
26
+ return self
27
+
28
+ def add_option(self, label: str, value: str = MISSING, description: Union[str, None] = None, emoji: Union[str, Emoji, PartialEmoji, None] = None, default: bool = False) -> "Menu":
29
+ """
30
+ Add an option to choice.
31
+ Only from string_select type !
32
+ """
33
+ if self.__menu.type != ComponentType.string_select:
34
+ raise ComponentTypeError()
35
+
36
+ self.__menu.add_option(label=label, value=value, description=description, emoji=emoji, default=default)
37
+ return self
38
+
39
+ @property
40
+ def component(self) -> Select:
41
+ """
42
+ Get the component
43
+ """
44
+ return self.__menu
45
+
46
+ @property
47
+ def callable(self) -> Callable:
48
+ """
49
+ Get the callable link to the menu
50
+ """
51
+ return self.__callable
52
+
53
+ @callable.setter
54
+ def callable(self, _callable: Callable):
55
+ """
56
+ Set the callable link to menu
57
+ """
@@ -0,0 +1,124 @@
1
+ from ..views.easy_modified_view import EasyModifiedViews
2
+ from .menu import Menu
3
+
4
+ from typing import Union, Callable
5
+ from discord.components import ComponentType
6
+ from discord import ChannelType, Member, TextChannel, ApplicationContext
7
+
8
+ class SelectMenu:
9
+ """
10
+ Create a simply select menu
11
+ """
12
+
13
+ def __init__(self, timeout: Union[float, None] = None, disabled_on_timeout: bool = False):
14
+ """
15
+ Init the select menu
16
+ """
17
+ self.__select_menu: EasyModifiedViews = EasyModifiedViews(timeout=timeout, disabled_on_timeout=disabled_on_timeout)
18
+
19
+ def add_string_select_menu(self, custom_id: str = None, placeholder: str = None, min_values: int = 1, max_values: int = 1, disabled=False, row=None) -> Menu:
20
+ """
21
+ Add a string select menu in the ui
22
+ :param custom_id: The ID of the select menu that gets received during an interaction. If not given then one is generated for you.
23
+ :param placeholder: The placeholder text that is shown if nothing is selected, if any.
24
+ :param max_values: The maximum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25.
25
+ :param min_values: The minimum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25.
26
+ :param disabled: Whether the select is disabled or not.
27
+ :param row: The relative row this select menu belongs to. A Discord component can only have 5 rows. By default, items are arranged automatically into those 5 rows. If you’d like to control the relative positioning of the row then passing an index is advised. For example, row=1 will show up before row=2. Defaults to None, which is automatic ordering. The row number must be between 0 and 4 (i.e. zero indexed).
28
+ """
29
+ return self.__global_add_component(ComponentType.string_select, custom_id=custom_id, placeholder=placeholder, max_values=max_values, min_values=min_values, disabled=disabled, row=row)
30
+
31
+ def add_user_select_menu(self, custom_id: str = None, placeholder: str = None, min_values: int = 1, max_values: int = 1, disabled=False, row=None) -> Menu:
32
+ """
33
+ Add an user select menu in the ui
34
+ :param custom_id: The ID of the select menu that gets received during an interaction. If not given then one is generated for you.
35
+ :param placeholder: The placeholder text that is shown if nothing is selected, if any.
36
+ :param max_values: The maximum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25.
37
+ :param min_values: The minimum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25.
38
+ :param disabled: Whether the select is disabled or not.
39
+ :param row: The relative row this select menu belongs to. A Discord component can only have 5 rows. By default, items are arranged automatically into those 5 rows. If you’d like to control the relative positioning of the row then passing an index is advised. For example, row=1 will show up before row=2. Defaults to None, which is automatic ordering. The row number must be between 0 and 4 (i.e. zero indexed).
40
+ """
41
+ return self.__global_add_component(ComponentType.user_select, custom_id=custom_id, placeholder=placeholder, max_values=max_values, min_values=min_values, disabled=disabled, row=row)
42
+
43
+ def add_role_select_menu(self, custom_id: str = None, placeholder: str = None, min_values: int = 1, max_values: int = 1, disabled=False, row=None) -> Menu:
44
+ """
45
+ Add a role select menu in the ui
46
+ :param custom_id: The ID of the select menu that gets received during an interaction. If not given then one is generated for you.
47
+ :param placeholder: The placeholder text that is shown if nothing is selected, if any.
48
+ :param max_values: The maximum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25.
49
+ :param min_values: The minimum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25.
50
+ :param disabled: Whether the select is disabled or not.
51
+ :param row: The relative row this select menu belongs to. A Discord component can only have 5 rows. By default, items are arranged automatically into those 5 rows. If you’d like to control the relative positioning of the row then passing an index is advised. For example, row=1 will show up before row=2. Defaults to None, which is automatic ordering. The row number must be between 0 and 4 (i.e. zero indexed).
52
+ """
53
+ return self.__global_add_component(ComponentType.role_select, custom_id=custom_id, placeholder=placeholder, max_values=max_values, min_values=min_values, disabled=disabled, row=row)
54
+
55
+ def add_mentionnable_select_menu(self, custom_id: str = None, placeholder: str = None, min_values: int = 1, max_values: int = 1, disabled=False, row=None) -> Menu:
56
+ """
57
+ Add a role select menu in the ui
58
+ :param custom_id: The ID of the select menu that gets received during an interaction. If not given then one is generated for you.
59
+ :param placeholder: The placeholder text that is shown if nothing is selected, if any.
60
+ :param max_values: The maximum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25.
61
+ :param min_values: The minimum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25.
62
+ :param disabled: Whether the select is disabled or not.
63
+ :param row: The relative row this select menu belongs to. A Discord component can only have 5 rows. By default, items are arranged automatically into those 5 rows. If you’d like to control the relative positioning of the row then passing an index is advised. For example, row=1 will show up before row=2. Defaults to None, which is automatic ordering. The row number must be between 0 and 4 (i.e. zero indexed).
64
+ """
65
+ return self.__global_add_component(ComponentType.mentionable_select, custom_id=custom_id, placeholder=placeholder, max_values=max_values, min_values=min_values, disabled=disabled, row=row)
66
+
67
+ def add_channel_select_menu(self, custom_id: str = None, placeholder: str = None, min_values: int = 1, max_values: int = 1, disabled=False, row=None, channel_types: list[ChannelType] = None):
68
+ """
69
+ Add a role select menu in the ui
70
+ :param custom_id: The ID of the select menu that gets received during an interaction. If not given then one is generated for you.
71
+ :param placeholder: The placeholder text that is shown if nothing is selected, if any.
72
+ :param max_values: The maximum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25.
73
+ :param min_values: The minimum number of items that must be chosen for this select menu. Defaults to 1 and must be between 1 and 25.
74
+ :param disabled: Whether the select is disabled or not.
75
+ :param row: The relative row this select menu belongs to. A Discord component can only have 5 rows. By default, items are arranged automatically into those 5 rows. If you’d like to control the relative positioning of the row then passing an index is advised. For example, row=1 will show up before row=2. Defaults to None, which is automatic ordering. The row number must be between 0 and 4 (i.e. zero indexed).
76
+ :param channel_types: A list of channel types that can be selected in this menu.
77
+ """
78
+ return self.__global_add_component(ComponentType.channel_select, custom_id=custom_id, placeholder=placeholder, max_values=max_values, min_values=min_values, disabled=disabled, row=row, channel_types=channel_types)
79
+
80
+ def __global_add_component(self, component_type: ComponentType,
81
+ custom_id: Union[str, None] = None,
82
+ placeholder: Union[str, None] = None,
83
+ min_values: int = 1,
84
+ max_values: int = 1,
85
+ disabled: bool = False,
86
+ row: Union[int, None] = None,
87
+ channel_types: Union[ChannelType, None] = None) -> Menu:
88
+ """
89
+ global function to add a Select component
90
+ """
91
+ menu = Menu(component_type,
92
+ self.__select_menu,
93
+ **{'custom_id': custom_id, 'placeholder': placeholder, 'min_values': min_values,
94
+ 'max_values': max_values, 'disabled': disabled, 'row': row, 'channel_types': channel_types})
95
+
96
+ self.__select_menu.add_items(menu.component)
97
+
98
+ return menu
99
+
100
+ def set_callable(self, *custom_ids: str, _callable : Callable):
101
+ """
102
+ Set a callable for the menu associated with the custom_id
103
+ :param custom_ids: IDs to menus
104
+ """
105
+ self.__select_menu.set_callable(*custom_ids, _callable=_callable)
106
+
107
+ async def respond(self, ctx: ApplicationContext, *args, **kwargs) -> None:
108
+ """
109
+ Respond at the ApplicationContext
110
+ """
111
+ await self.__select_menu.respond(ctx=ctx, *args, view=self.__select_menu, **kwargs)
112
+
113
+ async def send(self, target: Union[Member, TextChannel], *args, **kwargs) -> None:
114
+ """
115
+ Send at the target
116
+ """
117
+ await self.__select_menu.send(target=target, *args, view=self.__select_menu, **kwargs)
118
+
119
+ @property
120
+ def get_view(self) -> EasyModifiedViews:
121
+ """
122
+ Get the current view
123
+ """
124
+ return self.__select_menu
@@ -0,0 +1,5 @@
1
+ from .start_multibot import Multibot
2
+ from .errors import *
3
+ from .runner import Runner
4
+ from .process_for_bots import ProcessBot
5
+ from .process_messages import ProcessMessage
@@ -0,0 +1,10 @@
1
+ class MultibotError(Exception):
2
+ pass
3
+
4
+
5
+ class BotNotFoundError(MultibotError):
6
+ """
7
+ If the bot is not found with the given name
8
+ """
9
+ def __init__(self, name: str):
10
+ super().__init__(f"{name} is not found")
@@ -0,0 +1,112 @@
1
+ from discord import AutoShardedBot, Bot
2
+ from random import choice
3
+ from string import ascii_letters
4
+ from asyncio import set_event_loop, new_event_loop, sleep, run, create_task
5
+ from multiprocessing import Queue
6
+
7
+ from .errors import *
8
+ from .runner import Runner
9
+ from .process_messages import ProcessMessage
10
+
11
+
12
+ class ProcessBot:
13
+
14
+ def __init__(self, queue_parent: Queue, queue_children: Queue, limit_bots_in_tread: int = -1):
15
+ """
16
+ Class to manage process and thread
17
+ """
18
+ self.__threads: dict = {}
19
+ self.__all_bots: dict = {}
20
+
21
+ self.__limit_bots_in_tread: int = limit_bots_in_tread
22
+
23
+ self.__queue_parent: Queue = queue_parent
24
+ self.__queue_children: Queue = queue_children
25
+ self.__loop = None
26
+ run(self.run_process())
27
+
28
+ async def run_process(self):
29
+ """
30
+ Function run with the process
31
+ """
32
+ await create_task(self.__message_process_receiver()) # Run the process
33
+
34
+ async def __message_process_receiver(self):
35
+ """
36
+ Wait message from parent process (always a dict with the key "parent_message")
37
+ """
38
+ while True:
39
+ await sleep(0.02)
40
+ while not self.__queue_children.empty():
41
+ try:
42
+ message = self.__queue_children.get_nowait()
43
+ await self.__decode_message(message)
44
+ except:
45
+ break
46
+
47
+ def __message_process_sender(self, message: dict):
48
+ """
49
+ Send a message to parent process
50
+ """
51
+ self.__queue_parent.put(message)
52
+
53
+ async def __decode_message(self, message: dict):
54
+ """
55
+ Decode the current message sent by the parent process
56
+ :param message: The message.
57
+ """
58
+ action = message['parent_message']
59
+
60
+ if ProcessMessage.ADD_BOT.value == action:
61
+ self.add_bot(**message)
62
+
63
+ elif ProcessMessage.RUN_ALL.value == action:
64
+ print("run all bots")
65
+
66
+ def add_bot(self, token: str, *args, autoshared: bool = False, name: str = None, **kwargs) -> None:
67
+ """
68
+ Add a bot in the instance to manage it.
69
+ Use this function to set the bot's intents and other subtleties.
70
+ :param name: The name of the bot to find it. If None, a random name is given
71
+ :param token: The token bot
72
+ :param autoshared: Autoshare the bot in Discord
73
+ :param args: all arguments of the Discord class Bot.
74
+ :param kwargs: all kwargs of the Discord class Bot
75
+ See : https://docs.pycord.dev/en/stable/api/clients.html#discord.Bot
76
+ """
77
+ print(f"Ajout du bot {name} avec le token {token}")
78
+ if name is None:
79
+ name = ''.join([choice(ascii_letters) for _ in range(20)])
80
+
81
+ if autoshared:
82
+ self.__all_bots[name] = {'runner': Runner(AutoShardedBot(*args, **kwargs)),
83
+ 'token': token,
84
+ 'thread': None}
85
+
86
+ else:
87
+ self.__all_bots[name] = {'runner': Runner(Bot(*args, **kwargs)),
88
+ 'token': token,
89
+ 'thread': None}
90
+
91
+ print(f"Envoi de la réponse 'coucou' pour {name}")
92
+ self.__message_process_sender({'children_message': "coucou"})
93
+
94
+
95
+ def get_bots_names(self) -> list[str]:
96
+ """
97
+ Return all bots names registered in the class.
98
+ """
99
+ print('coucou', self.__event)
100
+ return list(self.__all_bots.keys())
101
+
102
+
103
+ def get_runner(self, name: str) -> "Runner":
104
+ """
105
+ Run the bot runner associated with this name
106
+ :raise: BotNotFoundError
107
+ """
108
+
109
+ if name not in self.__all_bots.keys():
110
+ raise BotNotFoundError(name)
111
+
112
+ return self.__all_bots[name]['runner']
@@ -0,0 +1,7 @@
1
+ from enum import Enum
2
+
3
+
4
+ class ProcessMessage(Enum):
5
+
6
+ ADD_BOT = "add bot"
7
+ RUN_ALL = "run all"
@@ -0,0 +1,14 @@
1
+ from discord import AutoShardedBot, Bot
2
+ from typing import Union
3
+
4
+ class Runner:
5
+
6
+ def __init__(self, bot: Union[AutoShardedBot, Bot]):
7
+ """
8
+ Run the bot
9
+ """
10
+ self.bot: Union[AutoShardedBot, Bot] = bot
11
+
12
+ def __reduce__(self):
13
+ # Renvoyer un tuple avec les informations nécessaires pour reconstruire l'objet
14
+ return self.__class__, (self.bot,)
@@ -0,0 +1,80 @@
1
+
2
+ from typing import Union, Any
3
+ from multiprocessing import Process, Queue, set_start_method, get_start_method
4
+ from asyncio import create_task, sleep
5
+ from time import sleep as tsleep
6
+
7
+ from .process_for_bots import ProcessBot
8
+ from .process_messages import ProcessMessage
9
+
10
+
11
+ class Multibot:
12
+
13
+ def __init__(self, limit_bots_in_tread: int = 10):
14
+ """
15
+ Create an instance of Multibot_asyncio class to manage few bots with asyncio.
16
+ :param limit_bots_in_tread: Max running bot in a single asyncio loop in a thread.
17
+ """
18
+ if get_start_method() != "spawn":
19
+ set_start_method("spawn")
20
+
21
+ self.__queue_parent: Queue = Queue()
22
+ self.__queue_children: Queue = Queue()
23
+
24
+ self.__process: Union[Process] = Process(target=ProcessBot, args=(self.__queue_parent, self.__queue_children, limit_bots_in_tread)) # Process to run all bots
25
+
26
+ async def start_process(self) -> "Multibot":
27
+ """
28
+ Start the process. It is required !
29
+ """
30
+ self.__process.start()
31
+ create_task(self.__message_process_receiver())
32
+
33
+ def __message_process_sender(self, message: dict):
34
+ """
35
+ Send a message to children process
36
+ """
37
+ print(f"Message envoyé par le parent : {message}")
38
+ self.__queue_children.put(message)
39
+
40
+ async def __message_process_receiver(self):
41
+ """
42
+ Wait message from children process (always a dict with the key "children_message")
43
+ """
44
+ while True:
45
+ await sleep(0.02)
46
+ while not self.__queue_parent.empty():
47
+ try:
48
+ message = self.__queue_parent.get_nowait()
49
+ await self.__decode_message(message)
50
+ except:
51
+ break
52
+
53
+ async def __decode_message(self, message: Any):
54
+ """
55
+ Decode the current message sent by the parent process
56
+ :param message: The message.
57
+ """
58
+ print(message)
59
+
60
+ async def add_bot(self, token: str, name: str = None, autoshared: bool = False, **kwargs):
61
+ """
62
+ Add a bot
63
+ """
64
+ data = {
65
+ 'parent_message': ProcessMessage.ADD_BOT.value,
66
+ 'token': token,
67
+ 'name': name,
68
+ 'autoshared': autoshared,
69
+ }
70
+ data.update(kwargs)
71
+
72
+ self.__message_process_sender(data)
73
+
74
+ async def run_all_bots(self):
75
+ """
76
+ Run all bots
77
+ """
78
+ self.__message_process_sender({'parent_message': ProcessMessage.RUN_ALL.value})
79
+
80
+
@@ -13,7 +13,7 @@ class Pagination:
13
13
  Allows you to easily setup a view pagination
14
14
  """
15
15
 
16
- def __init__(self, timeout: Union[float, None] = None, disabled_on_timeout:bool = False):
16
+ def __init__(self, timeout: Union[float, None] = None, disabled_on_timeout: bool = False):
17
17
  """
18
18
  Initialisation for pagination
19
19
  :param timeout: The time before disable items on the view
@@ -25,7 +25,7 @@ class Pagination:
25
25
  self.__view.add_items(Button(label='◀', row=0, custom_id='back', style=ButtonStyle.blurple))
26
26
  self.__view.add_items(Button(label='▶', row=0, custom_id='forward', style=ButtonStyle.blurple))
27
27
  self.__view.add_items(Button(label='⏭', row=0, custom_id='forward+', style=ButtonStyle.blurple))
28
- self.__view.set_callable('back+', 'back', 'forward', 'forward+', coroutine=self.__turn_page)
28
+ self.__view.set_callable('back+', 'back', 'forward', 'forward+', _callable=self.__turn_page)
29
29
 
30
30
  self.__pages: list[tuple[tuple, dict]] = []
31
31
  self.__current_page: int = 0
@@ -44,7 +44,7 @@ class Pagination:
44
44
  Deletes pages in the order in which they were added
45
45
  **Start to 0 !**
46
46
 
47
- delete_pages(1,2,3,...)
47
+ delete_pages(0,1,2,3,...)
48
48
  """
49
49
  nbr_pages = len(self.__pages)-1
50
50
  for page_number in page_numbers:
@@ -54,7 +54,7 @@ class Pagination:
54
54
 
55
55
  del self.__pages[page_number]
56
56
 
57
- async def __turn_page(self, interaction: Interaction):
57
+ async def __turn_page(self, button, interaction: Interaction):
58
58
  """
59
59
  Turn the page when button is pressed
60
60
  """
@@ -91,19 +91,18 @@ class Pagination:
91
91
  # Acknowledge the interaction
92
92
  await interaction.response.defer(invisible=True)
93
93
 
94
- async def send(self, send_to: Union[Member, TextChannel]) -> None:
94
+ async def send(self, target: Union[Member, TextChannel]) -> None:
95
95
  """
96
96
  Send pagination without introduction message.
97
- :param send_to: The member or channel to send the pagination
97
+ :param target: The member or channel to send the pagination
98
98
  """
99
-
100
- await send_to.send(*self.__pages[0][0], **self.__pages[0][1], view=self.get_view)
99
+ await self.__view.send(ctx=target, *self.__pages[0][0], **self.__pages[0][1], view=self.get_view)
101
100
 
102
101
  async def respond(self, ctx: ApplicationContext) -> None:
103
102
  """
104
103
  Respond to the command call
105
104
  """
106
- await ctx.respond(*self.__pages[0][0], **self.__pages[0][1], view=self.get_view)
105
+ await self.__view.respond(ctx=ctx, *self.__pages[0][0], **self.__pages[0][1], view=self.get_view)
107
106
 
108
107
  @property
109
108
  def get_view(self) -> EasyModifiedViews:
@@ -1,6 +1,6 @@
1
- from discord import Interaction, ApplicationContext, Message
1
+ from discord import Interaction, ApplicationContext, Message, Member, TextChannel
2
2
  from discord.ui import View, Item
3
- from typing import Union, Callable, Coroutine, Iterable
3
+ from typing import Union, Callable, Iterable
4
4
 
5
5
  from ..typeViews import T_views
6
6
  from .errors import CustomIDNotFound
@@ -39,11 +39,16 @@ class EasyModifiedViews(View):
39
39
  """
40
40
  self.__ctx = await ctx.respond(*args, **kwargs)
41
41
 
42
+ async def send(self, target: Union[Member, TextChannel], *args, **kwargs) -> None:
43
+ """
44
+ Send at the target
45
+ """
46
+ self.__ctx = await target.send(*args, **kwargs)
47
+
42
48
  def add_items(self,
43
49
  *items: T_views) -> "EasyModifiedViews":
44
50
  """
45
51
  Add all items in the View.
46
- custom_id REQUIRED !
47
52
  """
48
53
 
49
54
  for ui in items:
@@ -75,7 +80,7 @@ class EasyModifiedViews(View):
75
80
 
76
81
  def set_callable_decorator(self, custom_id: str):
77
82
  """
78
- Decorator to set up a coroutine for the item
83
+ Decorator to set up a callable for the item
79
84
 
80
85
  **Interaction parameter is required in coroutine function !**
81
86
 
@@ -84,7 +89,7 @@ class EasyModifiedViews(View):
84
89
 
85
90
  @view.set_callable_decorator(custom_id='test_ID')
86
91
 
87
- async def rep(**interaction**):
92
+ async def rep(**UI**, **interaction**):
88
93
  await interaction.response.send_message('coucou !!!')
89
94
 
90
95
  await ctx.respond('coucou', view=view)
@@ -92,36 +97,36 @@ class EasyModifiedViews(View):
92
97
  :param custom_id: item ID of the view
93
98
  """
94
99
 
95
- def decorator(coroutine: Coroutine):
100
+ def decorator(_callable: Callable):
96
101
  self.__check_custom_id(custom_id)
97
102
 
98
- self.__callback[custom_id]['func'] = coroutine
99
- return coroutine
103
+ self.__callback[custom_id]['func'] = _callable
104
+ return _callable
100
105
 
101
106
  return decorator
102
107
 
103
- def set_callable(self, *custom_ids: str, coroutine: Coroutine):
108
+ def set_callable(self, *custom_ids: str, _callable: Callable):
104
109
  """
105
- set up a coroutine for items
110
+ set up a callable for items
106
111
  :param custom_ids: items IDs of the view
107
- :param coroutine: The coroutine linked
112
+ :param _callable: The callable linked
108
113
 
109
- **Interaction parameter is required in coroutine function !**
114
+ **UI and Interaction parameter is required in callable function !**
110
115
 
111
116
  view = EasyModifiedViews(None)
112
117
 
113
118
  view.add_view(discord.ui.Button(label='coucou', custom_id='test_ID'))
114
119
 
115
- async def rep(**interaction**):
120
+ async def rep(**UI**, **interaction**):
116
121
  await interaction.response.send_message('coucou !!!')
117
122
 
118
- view.set_callable(custom_id='test_ID', coroutine=rep)
123
+ view.set_callable(custom_id='test_ID', callable=rep)
119
124
  await ctx.respond('coucou', view=view)
120
125
  """
121
126
  for custom_id in custom_ids:
122
127
  self.__check_custom_id(custom_id)
123
128
 
124
- self.__callback[custom_id]['func'] = coroutine
129
+ self.__callback[custom_id]['func'] = _callable
125
130
 
126
131
  async def interaction_check(self, interaction: Interaction) -> bool:
127
132
  """
@@ -130,7 +135,7 @@ class EasyModifiedViews(View):
130
135
  func = self.__callback[interaction.custom_id]['func']
131
136
 
132
137
  if func is not None:
133
- await func(interaction)
138
+ await func(self.__callback[interaction.custom_id]['ui'], interaction)
134
139
 
135
140
  else:
136
141
  await interaction.response.defer(invisible=True)
@@ -263,3 +268,6 @@ class EasyModifiedViews(View):
263
268
  """
264
269
  self.__check_custom_id(custom_id)
265
270
  return self.__callback[custom_id]['ui']
271
+
272
+ def __str__(self):
273
+ return str(self.__callback)
@@ -1,13 +0,0 @@
1
- pycordViews/__init__.py,sha256=mK6mXFXlXBnvJpPjH9UI_iS54ICVh_0H3LEReQNJutU,135
2
- pycordViews/typeViews.py,sha256=5q_-FTUGMg2QjA7bsjbb2ep41Y4sm2sBPTCOV6b5X1w,122
3
- pycordViews/pagination/__init__.py,sha256=Z9BcdoTWyC1KXGwQ1_C0tu9rkZpdrrjEHwMmjXsckeE,81
4
- pycordViews/pagination/errors.py,sha256=CYb5gBcXx0kYDUDkNpfUrqSxQAcJE_qfpomWtUFOsTk,316
5
- pycordViews/pagination/pagination_view.py,sha256=ppcQ6e3RFlw9YXoRF_mRdVi4Pf4EomHWUMDtGxwTDbI,4267
6
- pycordViews/views/__init__.py,sha256=yligptZmw-np8tjKLr76SVmi0807Nk6jCyKkKYLhbCY,89
7
- pycordViews/views/easy_modified_view.py,sha256=7cLMKSx92xqT0c74gssgBfFUNBOsc7M4sSrrXwPmVtc,7835
8
- pycordViews/views/errors.py,sha256=0NBjBDaSFZChJua1ho9qyfbNzwXy1U6Kcob5CCUxBK8,218
9
- PycordViews-1.0.2.dist-info/LICENSE,sha256=lNgcw1_xb7QENAQi3uHGymaFtbs0RV-ihiCd7AoLQjA,1082
10
- PycordViews-1.0.2.dist-info/METADATA,sha256=0L5TlXIHwBlzsFq0FztkoSgimrTJPRCVxu7wppEQbBI,2077
11
- PycordViews-1.0.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
12
- PycordViews-1.0.2.dist-info/top_level.txt,sha256=oPtEDovMPk2PEh7P6fY3IAXvCbmwnG3sbcFIAyljb-Y,53
13
- PycordViews-1.0.2.dist-info/RECORD,,