PycordViews 1.2.25__py3-none-any.whl → 1.3.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.
- pycordViews/multibot/bot.py +55 -51
- pycordViews/multibot/multibot.py +13 -2
- pycordViews/multibot/process.py +14 -1
- pycordViews/pagination/pagination_view.py +5 -1
- {pycordviews-1.2.25.dist-info → pycordviews-1.3.0.dist-info}/METADATA +12 -6
- {pycordviews-1.2.25.dist-info → pycordviews-1.3.0.dist-info}/RECORD +9 -9
- {pycordviews-1.2.25.dist-info → pycordviews-1.3.0.dist-info}/WHEEL +1 -1
- {pycordviews-1.2.25.dist-info → pycordviews-1.3.0.dist-info}/licenses/LICENSE +0 -0
- {pycordviews-1.2.25.dist-info → pycordviews-1.3.0.dist-info}/top_level.txt +0 -0
pycordViews/multibot/bot.py
CHANGED
@@ -46,7 +46,13 @@ class DiscordBot:
|
|
46
46
|
else:
|
47
47
|
raise BotNotStartedError(self.__bot.user.name)
|
48
48
|
|
49
|
-
def
|
49
|
+
async def __stop_bot_in_thread(self):
|
50
|
+
"""
|
51
|
+
Clear le cache du bot de manière asynchrone
|
52
|
+
"""
|
53
|
+
await self.__bot.close()
|
54
|
+
|
55
|
+
def add_pyFile_commands(self, file: str, reload_command: bool, setup_function: str):
|
50
56
|
"""
|
51
57
|
Ajoute et charge un fichier de commande bot et ses dépendances.
|
52
58
|
Les fichiers doivent avoir une fonction appelée « setup » ou un équivalent passé en paramètre.
|
@@ -75,17 +81,13 @@ class DiscordBot:
|
|
75
81
|
Ne recharge que le fichier et non les commandes du bot !
|
76
82
|
:param file: Le chemin d'accès relatif ou absolue du fichier
|
77
83
|
"""
|
78
|
-
print('ok')
|
79
84
|
module_name = path.splitext(path.basename(file))[0]
|
80
85
|
module_found = False
|
81
86
|
|
82
87
|
# Mise à jour du module et de son setup
|
83
|
-
print(self.__imported_module)
|
84
88
|
for imported in self.__imported_module:
|
85
|
-
|
89
|
+
|
86
90
|
if imported['module'].__name__ == module_name:
|
87
|
-
print('reload module :', module_name)
|
88
|
-
reload(imported['module'])
|
89
91
|
imported['setup_function'] = setup_function
|
90
92
|
module_found = True
|
91
93
|
break
|
@@ -95,7 +97,6 @@ class DiscordBot:
|
|
95
97
|
|
96
98
|
# Supprimer toutes les commandes du bot
|
97
99
|
for command in self.__bot.application_commands:
|
98
|
-
print('del commande', command.name)
|
99
100
|
self.__bot.remove_application_command(command)
|
100
101
|
|
101
102
|
# Réattacher toutes les commandes en réexécutant tous les setup
|
@@ -107,6 +108,42 @@ class DiscordBot:
|
|
107
108
|
reload_command=False
|
108
109
|
)
|
109
110
|
|
111
|
+
def reload_pyFile_commands(self):
|
112
|
+
"""
|
113
|
+
Recharge tous les fichiers de commandes du bot
|
114
|
+
"""
|
115
|
+
for imported in self.__imported_module:
|
116
|
+
self.modify_pyFile_commands(imported['file'], imported['setup_function'])
|
117
|
+
|
118
|
+
|
119
|
+
|
120
|
+
def __call_setup_function_in_command_file(self, file: str, module, setup_function: str, reload_command: bool):
|
121
|
+
"""
|
122
|
+
Appel la fonction de setup du module pour charger toutes les commandes du bot
|
123
|
+
:param file: Le chemin d'accès du fichier de commandes
|
124
|
+
:param module: Le module préchargé
|
125
|
+
:param setup_function: Le nom de la fonction de setup
|
126
|
+
:param reload_command: Si les commandes doivent être recharger sur le bot (envoie une requête à Discord) automatiquement
|
127
|
+
"""
|
128
|
+
if hasattr(module, setup_function): # si la fonction setup (ou autre) est dans le package
|
129
|
+
getattr(module, setup_function)(self.__bot)
|
130
|
+
|
131
|
+
########## permet de modifier le dictionnaire des modules importés si celui-ci existe déjà, sinon il l'ajoute à la liste des dictionaires des modules importés. Utile car on reload tout si un des modules est modifié
|
132
|
+
find = False
|
133
|
+
for mod in self.__imported_module:
|
134
|
+
if mod['module'].__name__ == module.__name__:
|
135
|
+
mod['setup_function'] = setup_function
|
136
|
+
find = True
|
137
|
+
break
|
138
|
+
|
139
|
+
if not find:
|
140
|
+
self.__imported_module.append({'setup_function': setup_function, 'module': module, 'file': file})
|
141
|
+
##########
|
142
|
+
|
143
|
+
if reload_command:
|
144
|
+
self.reload_commands()
|
145
|
+
else:
|
146
|
+
raise SetupCommandFunctionNotFound(setup_function, file)
|
110
147
|
|
111
148
|
def reload_commands(self, commands: Optional[list[ApplicationCommand]] = None):
|
112
149
|
"""
|
@@ -114,6 +151,17 @@ class DiscordBot:
|
|
114
151
|
"""
|
115
152
|
run_coroutine_threadsafe(self.__reload_commands(commands=commands), self.__loop).result(timeout=30)
|
116
153
|
|
154
|
+
async def __reload_commands(self, commands: Optional[list[ApplicationCommand]] = None):
|
155
|
+
"""
|
156
|
+
Recharge les commandes quand le bot est ready
|
157
|
+
"""
|
158
|
+
if self.__running_bot is not None:
|
159
|
+
while not self.is_ready:
|
160
|
+
await sleep(0.3)
|
161
|
+
await self.__bot.register_commands(commands=commands, method='individual', force=False)
|
162
|
+
else:
|
163
|
+
raise BotNotStartedError(self.__token)
|
164
|
+
|
117
165
|
|
118
166
|
@property
|
119
167
|
def is_running(self) -> bool:
|
@@ -135,12 +183,6 @@ class DiscordBot:
|
|
135
183
|
return self.__bot.is_ws_ratelimited()
|
136
184
|
|
137
185
|
|
138
|
-
async def __stop_bot_in_thread(self):
|
139
|
-
"""
|
140
|
-
Clear le cache du bot de manière asynchrone
|
141
|
-
"""
|
142
|
-
await self.__bot.close()
|
143
|
-
|
144
186
|
def close_ascyncio_loop(self):
|
145
187
|
"""
|
146
188
|
Ferme la boucle asyncio
|
@@ -153,42 +195,4 @@ class DiscordBot:
|
|
153
195
|
|
154
196
|
self.__loop.close()
|
155
197
|
|
156
|
-
async def __reload_commands(self, commands: Optional[list[ApplicationCommand]]):
|
157
|
-
"""
|
158
|
-
Recharge les commandes quand le bot est ready
|
159
|
-
"""
|
160
|
-
if self.__running_bot is not None:
|
161
|
-
while not self.is_ready:
|
162
|
-
await sleep(0.3)
|
163
|
-
await self.__bot.register_commands(commands=commands, method='individual', force=False)
|
164
|
-
else:
|
165
|
-
raise BotNotStartedError(self.__token)
|
166
|
-
|
167
|
-
def __call_setup_function_in_command_file(self, file: str, module, setup_function: str, reload_command: bool):
|
168
|
-
"""
|
169
|
-
Appel la fonction de setup du module pour charger toutes les commandes du bot
|
170
|
-
:param file: Le chemin d'accès du fichier de commandes
|
171
|
-
:param module: Le module préchargé
|
172
|
-
:param setup_function: Le nom de la fonction de setup
|
173
|
-
:param reload_command: Si les commandes doivent être recharger sur le bot (envoie une requête à Discord) automatiquement
|
174
|
-
"""
|
175
|
-
if hasattr(module, setup_function): # si la fonction setup (ou autre) est dans le package
|
176
|
-
getattr(module, setup_function)(self.__bot)
|
177
|
-
|
178
|
-
########## permet de modifier le dictionnaire des modules importés si celui-ci existe déjà, sinon il l'ajoute à la liste des dictionaires des modules importés. Utile car on reload tout si un des modules est modifié
|
179
|
-
find = False
|
180
|
-
for mod in self.__imported_module:
|
181
|
-
if mod['module'].__name__ == module.__name__:
|
182
|
-
mod['setup_function'] = setup_function
|
183
|
-
find = True
|
184
|
-
break
|
185
|
-
|
186
|
-
if not find:
|
187
|
-
self.__imported_module.append({'setup_function': setup_function, 'module': module})
|
188
|
-
##########
|
189
|
-
|
190
|
-
if reload_command:
|
191
|
-
self.reload_commands()
|
192
|
-
else:
|
193
|
-
raise SetupCommandFunctionNotFound(setup_function, file)
|
194
198
|
|
pycordViews/multibot/multibot.py
CHANGED
@@ -3,7 +3,7 @@ from multiprocessing.queues import Queue
|
|
3
3
|
from .process import ManageProcess
|
4
4
|
from discord import Intents
|
5
5
|
from sys import platform
|
6
|
-
from typing import Union
|
6
|
+
from typing import Union, Optional
|
7
7
|
|
8
8
|
|
9
9
|
class Multibot:
|
@@ -84,6 +84,17 @@ class Multibot:
|
|
84
84
|
self.__main_queue.put({'type': "STOP", 'bot_name': bot_name})
|
85
85
|
results.append(self.__get_data_queue())
|
86
86
|
return results
|
87
|
+
|
88
|
+
def restart(self, *bot_names: str) -> list[dict[str, str]]:
|
89
|
+
"""
|
90
|
+
Stop and start bots.
|
91
|
+
This function is slow ! It's shutdown all bots properly.
|
92
|
+
"""
|
93
|
+
results = []
|
94
|
+
for bot_name in bot_names:
|
95
|
+
self.__main_queue.put({'type': "RESTART", 'bot_name': bot_name})
|
96
|
+
results.append(self.__get_data_queue())
|
97
|
+
return results
|
87
98
|
|
88
99
|
def start_all(self) -> list[dict[str, list[str]]]:
|
89
100
|
"""
|
@@ -148,7 +159,7 @@ class Multibot:
|
|
148
159
|
|
149
160
|
:param bot_name: The bot's name to add commands file
|
150
161
|
:param file: Relative or absolute commands file's path
|
151
|
-
:param setup_function: Function name called by the process to give the Bot instance.
|
162
|
+
:param setup_function: Function name called by the process to give the Bot instance. Set to 'setup' by default.
|
152
163
|
:param reload_command: Reload all command in the fil and dependencies. Default : True
|
153
164
|
"""
|
154
165
|
self.__main_queue.put({'type': "ADD_COMMAND_FILE",
|
pycordViews/multibot/process.py
CHANGED
@@ -3,6 +3,7 @@ from .errors import BotAlreadyExistError, BotNotFoundError, MultibotError, BotNo
|
|
3
3
|
from .bot import DiscordBot
|
4
4
|
from discord import Intents
|
5
5
|
from immutableType import Str_
|
6
|
+
from typing import Optional
|
6
7
|
|
7
8
|
class ManageProcess:
|
8
9
|
|
@@ -19,6 +20,7 @@ class ManageProcess:
|
|
19
20
|
"REMOVE": self.remove_bot_to_process,
|
20
21
|
"START": self.start_bot_to_process,
|
21
22
|
"STOP": self.stop_bot_to_process,
|
23
|
+
"RESTART": self.restart_bot_to_process,
|
22
24
|
"IS_STARTED": self.is_started,
|
23
25
|
"IS_READY": self.is_ready,
|
24
26
|
"IS_WS_RATELIMITED": self.is_ws_ratelimited,
|
@@ -69,6 +71,17 @@ class ManageProcess:
|
|
69
71
|
self.__bots[bot_name].stop()
|
70
72
|
return f'{bot_name} bot stopped'
|
71
73
|
|
74
|
+
def restart_bot_to_process(self, bot_name: str) -> str:
|
75
|
+
"""
|
76
|
+
Redémarre un bot du processus
|
77
|
+
:param bot_name: Le nom du bot à redémarrer
|
78
|
+
"""
|
79
|
+
self.if_bot_no_exist(bot_name)
|
80
|
+
self.__bots[bot_name].stop()
|
81
|
+
self.__bots[bot_name].start()
|
82
|
+
self.__bots[bot_name].reload_pyFile_commands()
|
83
|
+
return f'{bot_name} bot restarted'
|
84
|
+
|
72
85
|
def start_all_bot_to_process(self) -> list[str]:
|
73
86
|
"""
|
74
87
|
Start tous les bots du processus
|
@@ -114,8 +127,8 @@ class ManageProcess:
|
|
114
127
|
:param reload_command : Recharge toutes les commandes dans le fichier et les dépendances. Défaut : True
|
115
128
|
"""
|
116
129
|
self.if_bot_no_exist(bot_name)
|
117
|
-
setup_function = Str_(setup_function).str_
|
118
130
|
file = Str_(file).str_
|
131
|
+
setup_function = Str_(setup_function).str_
|
119
132
|
self.__bots[bot_name].add_pyFile_commands(file=file, setup_function=setup_function, reload_command=reload_command)
|
120
133
|
|
121
134
|
def modify_pyFile_commands(self, bot_name: str, file: str, setup_function: str):
|
@@ -67,7 +67,7 @@ class Pagination:
|
|
67
67
|
page_count = len(self.__pages)
|
68
68
|
|
69
69
|
if page_count <= 1:
|
70
|
-
await self.__view.
|
70
|
+
await self.__view.shutdown()
|
71
71
|
await interaction.response.defer(invisible=True)
|
72
72
|
return
|
73
73
|
|
@@ -134,3 +134,7 @@ class Pagination:
|
|
134
134
|
(start to 0)
|
135
135
|
"""
|
136
136
|
return self.__current_page
|
137
|
+
|
138
|
+
@property
|
139
|
+
def get_view(self) -> EasyModifiedViews:
|
140
|
+
return self.__view
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: PycordViews
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.3.0
|
4
4
|
Summary: Views and multibot for py-cord library
|
5
5
|
Home-page: https://github.com/BOXERRMD/Py-cord_Views
|
6
6
|
Author: Chronos (alias BOXERRMD)
|
@@ -47,7 +47,7 @@ The paginator instance is used to create a view acting as a “book”, with pag
|
|
47
47
|
>
|
48
48
|
> > **Method** `send(target: Union[Member, TextChannel]) -> Any` : Send the pagination in dm member or channels
|
49
49
|
>
|
50
|
-
> > **Method** `respond(ctx: ApplicationContext) -> Any` : Respond at slash command call
|
50
|
+
> > **Method** `respond(ctx: Union[ApplicationContext, Interaction]) -> Any` : Respond at slash command call
|
51
51
|
>
|
52
52
|
> > **@property** `get_view -> EasyModifiedViews` : Return the pagination view. Can be used in `view` parameter to setup a view
|
53
53
|
>
|
@@ -75,7 +75,7 @@ async def pagination_command(ctx):
|
|
75
75
|
pages.add_page(content="My last page !", embed=None)# reset embed else he show the embed of the page before
|
76
76
|
|
77
77
|
await pages.respond(ctx=ctx) # respond to the command
|
78
|
-
await pages.send(
|
78
|
+
await pages.send(target=ctx.author) # send the message to the command author
|
79
79
|
|
80
80
|
bot.run("Your token")
|
81
81
|
```
|
@@ -95,11 +95,12 @@ The SelectMenu instance is used to create drop-down menus that can be easily mod
|
|
95
95
|
>
|
96
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
97
|
>
|
98
|
-
> > **Method** `set_callable(*custom_ids: str, _callable: Union[Callable, None], data: Optional[dict[str, Any]]
|
98
|
+
> > **Method** `set_callable(*custom_ids: str, _callable: Union[Callable, None], data: Optional[dict[str, Any]], autorised_roles : Optional[list[Union[int, Role]]] = None,
|
99
|
+
autorised_key: Optional[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. _data_ parameter is a dict fill with any values to pass in _(async function)_ parameters
|
99
100
|
>
|
100
101
|
> > **Method** `send(target: Union[Member, TextChannel]) -> Any` : Send the selectmenu in dm member or channels
|
101
102
|
>
|
102
|
-
> > **Method** `respond(ctx: ApplicationContext) -> Any` : Respond at slash command call
|
103
|
+
> > **Method** `respond(ctx: Union[ApplicationContext, Interaction]) -> Any` : Respond at slash command call and Interaction
|
103
104
|
>
|
104
105
|
> > **Method** `update() -> None` : Update the view dynamically if there was sent before.
|
105
106
|
>
|
@@ -113,7 +114,10 @@ The SelectMenu instance is used to create drop-down menus that can be easily mod
|
|
113
114
|
> ```python
|
114
115
|
> Menu(...)` # Not to be initialized by the user
|
115
116
|
> ```
|
116
|
-
> > **Method** `set_callable(_callable: Union[Callable, None]
|
117
|
+
> > **Method** `set_callable(_callable: Union[Callable, None],
|
118
|
+
data: Optional[dict[str, Any]] = None,
|
119
|
+
autorised_roles : Optional[list[Union[int, Role]]] = None,
|
120
|
+
autorised_key: Optional[Callable] = None) -> Menu` : Set a callable for menus associated. This callable _(async function)_ will be set to respond at selected menus interactions
|
117
121
|
>
|
118
122
|
> > **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
123
|
>
|
@@ -171,6 +175,8 @@ Each instance of this class creates a process where bots can be added. These bot
|
|
171
175
|
>
|
172
176
|
> > **Method** `stop(*bot_names: str) -> list[dict[str, str]]` : Stop bots properly
|
173
177
|
>
|
178
|
+
> > **Method** `restart(*bot_names: str) -> list[dict[str, str]]` : Restarts bots
|
179
|
+
>
|
174
180
|
> > **Method** `start_all() -> list[dict[str, list[str]]]` : Start all bot in the process
|
175
181
|
>
|
176
182
|
> > **Method** `stop_all() -> list[dict[str, list[str]]]` : Stop all bot in the process properly
|
@@ -10,19 +10,19 @@ pycordViews/modal/__init__.py,sha256=TFUX3z25oInBhBzoOQhnLbKmwArXo4IVVqBfN6y11Bo
|
|
10
10
|
pycordViews/modal/easy_modal_view.py,sha256=sNxfSg6sgoiKa3vc6eKa4RV7vNVNaSrI1XUJ9RMSD80,4281
|
11
11
|
pycordViews/modal/errors.py,sha256=nIGYyOS_oWH49Dj8ZGW53nnzaPmbvFbAo7ydikD5xWE,307
|
12
12
|
pycordViews/multibot/__init__.py,sha256=93Q_URiRUMsvwQJIqUnb75aq6SPM83yteSMrH0rmXMg,30
|
13
|
-
pycordViews/multibot/bot.py,sha256=
|
13
|
+
pycordViews/multibot/bot.py,sha256=pD-BPXNo7JeJPguTn7qLii0UzBSS4ITvmOPv8htKJG8,8284
|
14
14
|
pycordViews/multibot/errors.py,sha256=_xawL8jQZTajx253F4JKywFGVPdYf8vTALOMiNqJ9hs,1176
|
15
|
-
pycordViews/multibot/multibot.py,sha256=
|
16
|
-
pycordViews/multibot/process.py,sha256=
|
15
|
+
pycordViews/multibot/multibot.py,sha256=pmCBaYTa8arm9xnQSNbGrXFySEhyMoL4_uMLoiZjNmo,8054
|
16
|
+
pycordViews/multibot/process.py,sha256=hdeflJCy-OO2bGNmZm4KzDH8m0H9LEf_CUILX4KGQDU,8347
|
17
17
|
pycordViews/pagination/__init__.py,sha256=rvOp-nGXZ6EX_ojK1_1lcOHYUcrB0LG3DL7zwatkRPY,105
|
18
18
|
pycordViews/pagination/errors.py,sha256=CYb5gBcXx0kYDUDkNpfUrqSxQAcJE_qfpomWtUFOsTk,316
|
19
19
|
pycordViews/pagination/page.py,sha256=sKi_gCFt1euY7uJKWgMnxEqP1B4LMhUysxQ8oQbhNVQ,1147
|
20
|
-
pycordViews/pagination/pagination_view.py,sha256=
|
20
|
+
pycordViews/pagination/pagination_view.py,sha256=t6wvTLNTYg-w4eJQiyiX-LmEeR385SChifUzhiVSZBs,5793
|
21
21
|
pycordViews/views/__init__.py,sha256=yligptZmw-np8tjKLr76SVmi0807Nk6jCyKkKYLhbCY,89
|
22
22
|
pycordViews/views/easy_modified_view.py,sha256=HJfq_zSZaxzt84DLmFd-T2I7G79x4lgakI_dzX7jHh4,14000
|
23
23
|
pycordViews/views/errors.py,sha256=AkhGskuBjbFs0ZQdTDlVyfvAJ1WRMMQx2sAXUnYjmog,360
|
24
|
-
pycordviews-1.
|
25
|
-
pycordviews-1.
|
26
|
-
pycordviews-1.
|
27
|
-
pycordviews-1.
|
28
|
-
pycordviews-1.
|
24
|
+
pycordviews-1.3.0.dist-info/licenses/LICENSE,sha256=lNgcw1_xb7QENAQi3uHGymaFtbs0RV-ihiCd7AoLQjA,1082
|
25
|
+
pycordviews-1.3.0.dist-info/METADATA,sha256=jSvDwfxrJ-7GC9vNphmdrpKyhRn0IRreXwnPamFhL-w,12417
|
26
|
+
pycordviews-1.3.0.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
|
27
|
+
pycordviews-1.3.0.dist-info/top_level.txt,sha256=3NvgH6MjESe7Q6jb6aqHgdYrYb5NhxwxnoDyE6PkThY,125
|
28
|
+
pycordviews-1.3.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|