PycordViews 1.1.4__py3-none-any.whl → 1.2.0__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.
@@ -0,0 +1,217 @@
1
+ from multiprocessing import Queue
2
+ from .errors import BotAlreadyExistError, BotNotFoundError, MultibotError, BotNotStartedError
3
+ from .bot import DiscordBot
4
+ from discord import Intents
5
+ from immutableType import Str_
6
+
7
+ class ManageProcess:
8
+
9
+ def __init__(self, main_queue: Queue, process_queue: Queue):
10
+ """
11
+ Gère tous les bots dans un processus
12
+ """
13
+ self.__bots: dict[str, DiscordBot] = {}
14
+ self.main_queue: Queue = main_queue
15
+ self.process_queue: Queue = process_queue
16
+
17
+ self.commandes = {
18
+ "ADD": self.add_bot_to_process,
19
+ "REMOVE": self.remove_bot_to_process,
20
+ "START": self.start_bot_to_process,
21
+ "STOP": self.stop_bot_to_process,
22
+ "IS_STARTED": self.is_started,
23
+ "IS_READY": self.is_ready,
24
+ "IS_WS_RATELIMITED": self.is_ws_ratelimited,
25
+ "STOPALL": self.stop_all_bot_to_process,
26
+ "STARTALL": self.start_all_bot_to_process,
27
+ "BOT_COUNT": self.bot_count,
28
+ "STARTED_BOT_COUNT": self.started_bot_count,
29
+ "SHUTDOWN_BOT_COUNT": self.shutdown_bot_count,
30
+ "BOTS_bot_name": self.get_bots_bot_name,
31
+ "RELOAD_COMMANDS": self.reload_all_commands,
32
+ "ADD_COMMAND_FILE": self.add_pyFile_commands,
33
+ "MODIFY_COMMAND_FILE": self.modify_pyFile_commands
34
+ }
35
+
36
+ def run(self):
37
+ """
38
+ Boucle principale du processus, écoute la queue principale.
39
+ Doit comporter aubligatoirement un dictionnaire avec la clé 'type'
40
+ """
41
+ while True:
42
+ if not self.main_queue.empty():
43
+ command: dict = self.main_queue.get()
44
+ print(command)
45
+
46
+ c = command["type"]
47
+ if c in self.commandes.keys():
48
+ del command['type']
49
+ try:
50
+ result = self.commandes[c](**command)
51
+ self.process_queue.put({'status': 'success', 'message': result})
52
+ except MultibotError as e:
53
+ self.process_queue.put({'status': 'error', 'message': e})
54
+
55
+ def start_bot_to_process(self, bot_name: str) -> str:
56
+ """
57
+ Lance un unique bot
58
+ """
59
+ self.if_bot_no_exist(bot_name)
60
+ self.__bots[bot_name].start()
61
+ return f'{bot_name} bot started'
62
+
63
+ def stop_bot_to_process(self, bot_name: str) -> str:
64
+ """
65
+ Stop un bot du processus
66
+ :param bot_name: Le nom du bot à stopper
67
+ """
68
+ self.if_bot_no_exist(bot_name)
69
+ self.__bots[bot_name].stop()
70
+ return f'{bot_name} bot stopped'
71
+
72
+ def start_all_bot_to_process(self) -> list[str]:
73
+ """
74
+ Start tous les bots du processus
75
+ """
76
+ result = []
77
+ for bot in self.__bots.keys():
78
+ result.append(self.start_bot_to_process(bot))
79
+ return result
80
+
81
+ def stop_all_bot_to_process(self) -> list[str]:
82
+ """
83
+ Stop tous les bots du processus
84
+ """
85
+ result = []
86
+ for bot in self.__bots.keys():
87
+ result.append(self.stop_bot_to_process(bot))
88
+
89
+ return result
90
+
91
+ def add_bot_to_process(self, bot_name: str, token: str, intents: Intents) -> str:
92
+ """
93
+ Ajoute un bot au processus
94
+ :param bot_name: Le nom du bot
95
+ :param token: Le token du bot
96
+ :raise: BotAlreadyExistError si le bot existe déjà
97
+ """
98
+ if bot_name in self.__bots.keys():
99
+ raise BotAlreadyExistError(bot_name)
100
+ self.__bots[bot_name] = DiscordBot(token, intents)
101
+ return f'Bot {bot_name} added'
102
+
103
+ def add_pyFile_commands(self, bot_bot_name: str, file: str, setup_function: str, reload_command: bool):
104
+ """
105
+ Ajoute et charge un fichier de commande bot et ses dépendances.
106
+ Les fichiers doivent avoir une fonction appelée « setup » ou un équivalent passé en paramètre.
107
+
108
+ def setup(bot: Bot) :
109
+ ...
110
+
111
+ :param bot_bot_name : Le nom du bot à ajouter au fichier de commandes
112
+ :param file: Chemin relatif ou absolue du fichier de commande
113
+ :param setup_function : Nom de la fonction appelée par le processus pour donner l'instance de Bot.
114
+ :param reload_command : Recharge toutes les commandes dans le fichier et les dépendances. Défaut : True
115
+ """
116
+ self.if_bot_no_exist(bot_bot_name)
117
+ setup_function = Str_(setup_function).str_
118
+ file = Str_(file).str_
119
+ self.__bots[bot_bot_name].add_pyFile_commands(file=file, setup_function=setup_function, reload_command=reload_command)
120
+
121
+ def modify_pyFile_commands(self, bot_bot_name: str, file: str, setup_function: str):
122
+ """
123
+ Modifie un fichier de comandes et le recharge.
124
+ Ne recharge que le fichier et non les commandes du bot !
125
+ :param bot_bot_name: Le nom du bot
126
+ :param file: Le chemin d'accès relatif ou absolue du fichier
127
+ """
128
+ self.if_bot_no_exist(bot_bot_name)
129
+ file = Str_(file).str_
130
+ self.__bots[bot_bot_name].modify_pyFile_commands(file=file, setup_function=setup_function)
131
+
132
+
133
+ def reload_all_commands(self, bot_name: str):
134
+ """
135
+ Recharge toutes les commandes sur Discord
136
+ """
137
+ self.if_bot_no_exist(bot_name)
138
+ self.__bots[bot_name].reload_commands()
139
+ return f'Bot {bot_name} commands reloaded'
140
+
141
+ def remove_bot_to_process(self, bot_name: str) -> str:
142
+ """
143
+ Coupe et enlève un bot au processus
144
+ :param bot_name: Le nom du bot à retirer
145
+ :raise:
146
+ """
147
+ self.if_bot_no_exist(bot_name)
148
+ try:
149
+ self.__bots[bot_name].stop()
150
+ except BotNotStartedError:
151
+ pass
152
+ self.__bots[bot_name].close_ascyncio_loop()
153
+ del self.__bots[bot_name]
154
+ return f'Bot {bot_name} removed'
155
+
156
+ def is_started(self, bot_name: str) -> bool:
157
+ """
158
+ Regarde si la connexion au Websocket est effectué
159
+ :param bot_name: Le nom du bot à vérifier
160
+ """
161
+ self.if_bot_no_exist(bot_name)
162
+ return self.__bots[bot_name].is_running
163
+
164
+ def is_ready(self, bot_name: str) -> bool:
165
+ """
166
+ Regarde si le bot est ready
167
+ :param bot_name: Le nom du bot à vérifier
168
+ """
169
+ self.if_bot_no_exist(bot_name)
170
+ return self.__bots[bot_name].is_ready
171
+
172
+ def is_ws_ratelimited(self, bot_name: str) -> bool:
173
+ """
174
+ Regarde si le bot est ratelimit
175
+ :param bot_name: Le nom du bot à vérifier
176
+ """
177
+ self.if_bot_no_exist(bot_name)
178
+ return self.__bots[bot_name].is_ws_ratelimited
179
+
180
+ def if_bot_no_exist(self, bot_name: str) -> None:
181
+ """
182
+ Regarde si le bot existe dans la class
183
+ """
184
+ if bot_name not in self.__bots.keys():
185
+ raise BotNotFoundError(bot_name)
186
+
187
+ def bot_count(self) -> int:
188
+ """
189
+ Renvoie le nombre de bot au total
190
+ """
191
+ return len(self.__bots)
192
+
193
+ def started_bot_count(self) -> int:
194
+ """
195
+ Renvoie le nombre de bot démarré au total
196
+ """
197
+ s = 0
198
+ for bot in self.__bots.values():
199
+ if bot.is_running:
200
+ s += 1
201
+ return s
202
+
203
+ def shutdown_bot_count(self) -> int:
204
+ """
205
+ Renvoie le nombre de bot arrêter au total
206
+ """
207
+ s = 0
208
+ for bot in self.__bots.values():
209
+ if not bot.is_running:
210
+ s += 1
211
+ return s
212
+
213
+ def get_bots_bot_name(self) -> list[str]:
214
+ """
215
+ Renvoie tous les noms des bots entrée par l'utilisateur
216
+ """
217
+ return list(self.__bots.keys())
@@ -0,0 +1,241 @@
1
+ Metadata-Version: 2.4
2
+ Name: PycordViews
3
+ Version: 1.2.0
4
+ Summary: Views and multibot for py-cord library
5
+ Home-page: https://github.com/BOXERRMD/Py-cord_Views
6
+ Author: Chronos (alias BOXERRMD)
7
+ Author-email: vagabonwalybi@gmail.com
8
+ Maintainer: Chronos
9
+ License: MIT License
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Natural Language :: English
13
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 11
14
+ Classifier: Operating System :: Microsoft :: Windows :: Windows 10
15
+ Classifier: Operating System :: POSIX :: Linux
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Programming Language :: Python :: 3.9
18
+ Requires-Python: >=3.9
19
+ Description-Content-Type: text/markdown
20
+ License-File: LICENSE
21
+ Requires-Dist: immutable-Python-type
22
+ Dynamic: author
23
+ Dynamic: author-email
24
+ Dynamic: classifier
25
+ Dynamic: description
26
+ Dynamic: description-content-type
27
+ Dynamic: home-page
28
+ Dynamic: license
29
+ Dynamic: license-file
30
+ Dynamic: maintainer
31
+ Dynamic: requires-dist
32
+ Dynamic: requires-python
33
+ Dynamic: summary
34
+
35
+ # Py-cord_Views
36
+ Views for py-cord library
37
+
38
+ # Paginator
39
+ The paginator instance is used to create a view acting as a “book”, with pages that can be turned using buttons.
40
+ ## `Paginator`
41
+ > ```python
42
+ > Paginator(timeout: Union[float, None] = None, disabled_on_timeout: bool = False)`
43
+ > ```
44
+ > > **Method** `add_page(*args, **kwargs) -> Pagination` : add a new page with send message function parameters _(content, embed, embeds, files...)_
45
+ >
46
+ > > **Method** `delete_pages(*page_numbers: Union[str, int]) -> Pagination` : Deletes pages in the order in which they were added _(start to 0)_
47
+ >
48
+ > > **Method** `send(target: Union[Member, TextChannel]) -> Any` : Send the pagination in dm member or channels
49
+ >
50
+ > > **Method** `respond(ctx: ApplicationContext) -> Any` : Respond at slash command call
51
+ >
52
+ > > **@property** `get_view -> EasyModifiedViews` : Return the pagination view. Can be used in `view` parameter to setup a view
53
+ >
54
+ > > **@property** `get_page -> int` : get the showed page number
55
+
56
+ ```python
57
+ from pycordViews.pagination import Pagination
58
+ import discord
59
+
60
+ intents = discord.Intents.all()
61
+ bot = discord.AutoShardedBot(intents=intents)
62
+
63
+ @bot.command(name="My command paginator", description="...")
64
+ async def pagination_command(ctx):
65
+ """
66
+ Create a command pagination
67
+ """
68
+ pages: Pagination = Pagination(timeout=None, disabled_on_timeout=False)
69
+
70
+ pages.add_page(content="It's my first page !!", embed=None)# reset embed else he show the embed of the page after
71
+
72
+ embed = discord.Embed(title="My embed title", description="..........")
73
+ pages.add_page(content=None, embed=embed) # reset content else he show the content of the page before
74
+
75
+ pages.add_page(content="My last page !", embed=None)# reset embed else he show the embed of the page before
76
+
77
+ await pages.respond(ctx=ctx) # respond to the command
78
+ await pages.send(send_to=ctx.author) # send the message to the command author
79
+
80
+ bot.run("Your token")
81
+ ```
82
+
83
+ # SelectMenu
84
+ The SelectMenu instance is used to create drop-down menus that can be easily modified at will.
85
+
86
+ ## `SelectMenu`
87
+ > ```python
88
+ > SelectMenu(timeout: Union[float, None] = None, disabled_on_timeout: bool = False)`
89
+ > ```
90
+ > > **Method** `add_string_select_menu(custom_id: str = None, placeholder: str = None, min_values: int = 1, max_values: int = 1, disabled=False, row=None) -> Menu` : Add a string select menu in the ui. Return Menu instance to set options
91
+ >
92
+ > > **Method** `add_user_select_menu(custom_id: str = None, placeholder: str = None, min_values: int = 1, max_values: int = 1, disabled=False, row=None) -> Menu` : Add a user select menu in the ui. Return Menu instance to set options
93
+ >
94
+ > > **Method** `add_role_select_menu(custom_id: str = None, placeholder: str = None, min_values: int = 1, max_values: int = 1, disabled=False, row=None) -> Menu` Add a role select menu in the ui. Return Menu instance to set options
95
+ >
96
+ > > **Method** `add_mentionnable_select_menu(custom_id: str = None, placeholder: str = None, min_values: int = 1, max_values: int = 1, disabled=False, row=None) -> Menu` : Add a mentionable select menu in the ui. Return Menu instance to set options
97
+ >
98
+ > > **Method** `set_callable(*custom_ids: str, _callable: Union[Callable, None]) -> SelectMenu` : Set a callable for menus associated with custom_ids. This callable _(async function)_ will be set to respond at selected menus interactions
99
+ >
100
+ > > **Method** `send(target: Union[Member, TextChannel]) -> Any` : Send the selectmenu in dm member or channels
101
+ >
102
+ > > **Method** `respond(ctx: ApplicationContext) -> Any` : Respond at slash command call
103
+ >
104
+ > > **Method** `update() -> None` : Update the view dynamically if there was sent before.
105
+ >
106
+ > > **@Method** `get_callable(self, custom_id: str) -> Union[Callable, None]` : Get the callable _async_ function link to the custom_id ui. If any callable set, return None
107
+ >
108
+ > > **@property** `get_view -> EasyModifiedViews` : Return the selectmenu view. Can be used in `view` parameter to setup a view
109
+
110
+ ### Menu
111
+
112
+ ## `Menu`
113
+ > ```python
114
+ > Menu(...)` # Not to be initialized by the user
115
+ > ```
116
+ > > **Method** `set_callable(_callable: Union[Callable, None]) -> Menu` : Set a callable for menus associated. This callable _(async function)_ will be set to respond at selected menus interactions
117
+ >
118
+ > > **Method** `add_option(label: str, value: str = MISSING, description: Union[str, None] = None, emoji: Union[str, Emoji, PartialEmoji, None] = None, default: bool = False) -> Menu` : Add a string select option. Only for string select menu !
119
+ >
120
+ > > **Method** `remove_options(*labels: str) -> Menu` : Remove options with labels. Only for string select menu !
121
+ >
122
+ > > **Method** `update_option(current_label: str, new_label: str = None, value: str = None, description: Union[str, None] = None, emoji: Union[str, Emoji, PartialEmoji, None] = None, default: Union[bool, None] = None) -> Menu` : Update option associated with `current_label` parameter
123
+ >
124
+ > > **@property** `component -> CustomSelect` : Return the Select component class
125
+ >
126
+ > > **@property** `selectmenu -> SelectMenu` : Return the current SelectMenu instance associated
127
+ >
128
+ > > **@property** `callable -> Callable` : Return the current callable menu
129
+
130
+ ```python
131
+ from pycordViews.menu import SelectMenu
132
+ import discord
133
+
134
+ intents = discord.Intents.all()
135
+ bot = discord.AutoShardedBot(intents=intents)
136
+
137
+ @bot.command(name="My command select")
138
+ async def select_command(ctx):
139
+ """
140
+ Create a command select
141
+ """
142
+ async def your_response(select, interaction):
143
+ await interaction.response.send(f"You have selected {select.values[0]} !")
144
+
145
+ my_selector = SelectMenu(timeout=None, disabled_on_timeout=False) # A basic selector menu
146
+ my_menu = my_selector.add_string_select_menu(placeholder="Choice anything !") # add string_select UI
147
+
148
+ my_menu.add_option(label="My first choice !", emoji="😊", default=True, description="It's the first choice !", value='first choice')
149
+ my_menu.add_option(label="My second choice !", value='second choice')
150
+ my_menu.set_callable(your_response)
151
+
152
+ await my_selector.respond(ctx)
153
+
154
+ bot.run("Your token")
155
+ ```
156
+
157
+ # Multibot
158
+ The Multibot instance is used to manage several bots dynamically.
159
+
160
+ Each instance of this class creates a process where bots can be added. These bots will each be launched in a different thread with their own asyncio loop.
161
+
162
+ ## `Multibot`
163
+ > ```python
164
+ > Multibot(global_timeout: int = 30) # global_timeout is the time in seconds the program waits before abandoning the request
165
+ > ```
166
+ > > **Method** `add_bot(bot_name: str, token: str, intents: Intents) -> None` : Add a bot. The name given here is not the real bot name, it's juste an ID
167
+ >
168
+ > > **Method** `remove_bot(bot_name: str) -> dict[str, str]` : Remove à bot. If the bot is online, it will turn off properly. It can take a long time !
169
+ >
170
+ > > **Method** `start(*bot_names: str) -> list[dict[str, str]]` : Start bots
171
+ >
172
+ > > **Method** `def stop(*bot_names: str) -> list[dict[str, str]]` : Stop bots properly
173
+ >
174
+ > > **Method** `start_all() -> list[dict[str, list[str]]]` : Start all bot in the process
175
+ >
176
+ > > **Method** `stop_all() -> list[dict[str, list[str]]]` : Stop all bot in the process properly
177
+ >
178
+ > > **Method** `is_started(bot_name: str) -> bool` : Return if the bot is connected at the Discord WebSocket
179
+ >
180
+ > > **Method** `is_ready(bot_name: str) -> bool` : Return if the bot is ready in Discord
181
+ >
182
+ > > **Method** `is_ws_ratelimited(bot_name: str) -> bool` : Return if the bot is rate limited by Discord
183
+ >
184
+ > > **Method** `reload_commands(*bot_names: str) -> list[dict[str, str]]` : Reload all commands for each bot passed in parameters
185
+ >
186
+ > > **Method** `add_pyFile_commands(bot_name: str, file: str, setup_function: str = 'setup', reload_command: bool = True) -> dict[str, str]` : Add a python Discord command file to the bot. `file` parameter require a file path, absolute or not. By default, it automatically reloads commands on the bot after adding the file.
187
+ > >
188
+ > > ### _Blob_commands.py_
189
+ > > ```python
190
+ > > """
191
+ > > Discord command file example. Follow it !
192
+ > > This file doesn't have 'bot.run()' function. It's managed by Multibot instance.
193
+ > > """
194
+ > >
195
+ > > from discord import Bot, ApplicationContext, Message # autoaticly imported by importlib module
196
+ > >
197
+ > > # this function is called when the bot load a python file command. It is mandatory to have it with a bot parameter !
198
+ > > def setup(bot: Bot):
199
+ > > """
200
+ > > Function called by the process and give the bot instance.
201
+ > > This function is mandatory to have it with a bot parameter but can be renamed with 'setup_function' parameter in 'add_pyFile_commands' method.
202
+ > > Every discord command and discord event can be in this function, but you can make function and class outside setup function.
203
+ > > -> bot : Instance of your started bot.
204
+ > > """
205
+ > > @bot.command()
206
+ > > async def my_first_command(ctx: ApplicationContext):
207
+ > > await ctx.respond("It's my first command !")
208
+ > >
209
+ > > @bot.event
210
+ > > async def on_message(message: Message):
211
+ > > await message.add_reaction(emoji="😊")
212
+ > >
213
+ > > # You don't need 'bot.run(...)' here !
214
+ > > ```
215
+ >
216
+ > > **Method** `modify_pyFile_commands(bot_name: str, file: str, setup_function: str = 'setup') -> dict[str, str]` : Modify python discord command file and setup function. This method doesn't reload automatically commands on the bot. Use `reload_commands` after. `file` parameter require a file path, absolute or not.
217
+ >
218
+ > > **@property** `bot_count -> int` : Return the total number of bots
219
+ >
220
+ > > **@property** `started_bot_count -> int` : Return the total number of started bots
221
+ >
222
+ > > **@property** `shutdown_bot_count( -> int` : Return the total number of shutdown bots
223
+ >
224
+ > > **@property** `get_bots_name -> list[str]` : Return all bots name _(not real name of bots)_
225
+ ```python
226
+ from pycordViews.multibot import Multibot
227
+ from discord import Intents
228
+
229
+ if __name__ == '__main__': # Obligatory !
230
+ process = Multibot()
231
+
232
+ process.add_bot(bot_name="Blob", token="TOKEN FIRST BOT", intents=Intents.all())
233
+ process.add_bot(bot_name="Bee", token="TOKEN SECOND BOT", intents=Intents.all())
234
+
235
+ process.start_all()
236
+ process.add_pyFile_commands(bot_name='Blob', file='Blob_commands.py', reload_command=True)
237
+ process.add_pyFile_commands(bot_name='Bee', file='Bee_commandes.py', reload_command=True)
238
+
239
+ process.modify_pyFile_commands(bot_name='Blob', file='others_commands/Blob2_commands.py', setup_function='started_bot')
240
+ process.reload_commands('Blob')
241
+ ```
@@ -0,0 +1,21 @@
1
+ pycordViews/__init__.py,sha256=gJmACNCnfY5Q00aUFVODZ6Tkfdo3mgGlolPNSZnzT8k,225
2
+ pycordViews/menu/__init__.py,sha256=QUXA9ezyeTScvS1kxMNFgKEbZMsPq5yUnWWgbXCytCk,97
3
+ pycordViews/menu/errors.py,sha256=0Um-oH5qMdWSZB_bGlqILsf9WSDtC4n_HwkheekiMV4,480
4
+ pycordViews/menu/menu.py,sha256=3D13C5Vs69w9SlrnixBfF0riY48jORi8JcYte65YFPs,4306
5
+ pycordViews/menu/selectMenu.py,sha256=oYydLtoQm7YRjnFII2af5cUfIZ8ci_86lk0Il5TGYTw,10459
6
+ pycordViews/multibot/__init__.py,sha256=93Q_URiRUMsvwQJIqUnb75aq6SPM83yteSMrH0rmXMg,30
7
+ pycordViews/multibot/bot.py,sha256=UrRqSSmtFpkQKAqeunHxIy_O5DgO1gcW-nMEQ9yNdAo,8267
8
+ pycordViews/multibot/errors.py,sha256=_xawL8jQZTajx253F4JKywFGVPdYf8vTALOMiNqJ9hs,1176
9
+ pycordViews/multibot/multibot.py,sha256=xko7AdgkuYJgefKl39Rmz9fpk8R02nGdSWf6zCt_CxQ,7562
10
+ pycordViews/multibot/process.py,sha256=MYhOUG1egKK_I8sJ8y4yW_avZut8VIyGO5D2d-CCBV4,7895
11
+ pycordViews/pagination/__init__.py,sha256=Z9BcdoTWyC1KXGwQ1_C0tu9rkZpdrrjEHwMmjXsckeE,81
12
+ pycordViews/pagination/errors.py,sha256=CYb5gBcXx0kYDUDkNpfUrqSxQAcJE_qfpomWtUFOsTk,316
13
+ pycordViews/pagination/pagination_view.py,sha256=sJHDkmiTGwJzxfAUQijF2ry6NPVwepJvbdkAvA6j0es,4846
14
+ pycordViews/views/__init__.py,sha256=yligptZmw-np8tjKLr76SVmi0807Nk6jCyKkKYLhbCY,89
15
+ pycordViews/views/easy_modified_view.py,sha256=QuS8AnkTLHrdKl7Tya0_gjuwhWHLIvMAEK3DsyE1ALg,8986
16
+ pycordViews/views/errors.py,sha256=0NBjBDaSFZChJua1ho9qyfbNzwXy1U6Kcob5CCUxBK8,218
17
+ pycordviews-1.2.0.dist-info/licenses/LICENSE,sha256=lNgcw1_xb7QENAQi3uHGymaFtbs0RV-ihiCd7AoLQjA,1082
18
+ pycordviews-1.2.0.dist-info/METADATA,sha256=ij56btgSo1NEh_GL3G4CDiPO3Rhr6exSE0OeeERlNCY,11828
19
+ pycordviews-1.2.0.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
20
+ pycordviews-1.2.0.dist-info/top_level.txt,sha256=nqBU40KmnSCjtry8kmv97-RvZC-8xQrhrrloOJX2ROs,91
21
+ pycordviews-1.2.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (76.0.0)
2
+ Generator: setuptools (78.1.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,112 +0,0 @@
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']
@@ -1,7 +0,0 @@
1
- from enum import Enum
2
-
3
-
4
- class ProcessMessage(Enum):
5
-
6
- ADD_BOT = "add bot"
7
- RUN_ALL = "run all"
@@ -1,14 +0,0 @@
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,)