PycordViews 1.1.2__tar.gz → 1.1.4__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.
Files changed (30) hide show
  1. {pycordviews-1.1.2 → pycordviews-1.1.4}/PKG-INFO +1 -1
  2. {pycordviews-1.1.2 → pycordviews-1.1.4}/PycordViews.egg-info/PKG-INFO +1 -1
  3. {pycordviews-1.1.2 → pycordviews-1.1.4}/PycordViews.egg-info/SOURCES.txt +0 -1
  4. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/__init__.py +1 -1
  5. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/menu/__init__.py +1 -1
  6. pycordviews-1.1.4/pycordViews/menu/menu.py +118 -0
  7. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/menu/selectMenu.py +27 -8
  8. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/pagination/pagination_view.py +15 -6
  9. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/views/easy_modified_view.py +40 -18
  10. {pycordviews-1.1.2 → pycordviews-1.1.4}/setup.py +1 -1
  11. pycordviews-1.1.2/pycordViews/menu/menu.py +0 -57
  12. pycordviews-1.1.2/pycordViews/typeViews.py +0 -4
  13. {pycordviews-1.1.2 → pycordviews-1.1.4}/LICENSE +0 -0
  14. {pycordviews-1.1.2 → pycordviews-1.1.4}/PycordViews.egg-info/dependency_links.txt +0 -0
  15. {pycordviews-1.1.2 → pycordviews-1.1.4}/PycordViews.egg-info/requires.txt +0 -0
  16. {pycordviews-1.1.2 → pycordviews-1.1.4}/PycordViews.egg-info/top_level.txt +0 -0
  17. {pycordviews-1.1.2 → pycordviews-1.1.4}/README.md +0 -0
  18. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/menu/errors.py +0 -0
  19. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/multibot/__init__.py +0 -0
  20. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/multibot/errors.py +0 -0
  21. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/multibot/process_for_bots.py +0 -0
  22. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/multibot/process_messages.py +0 -0
  23. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/multibot/runner.py +0 -0
  24. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/multibot/start_multibot.py +0 -0
  25. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/pagination/__init__.py +0 -0
  26. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/pagination/errors.py +0 -0
  27. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/views/__init__.py +0 -0
  28. {pycordviews-1.1.2 → pycordviews-1.1.4}/pycordViews/views/errors.py +0 -0
  29. {pycordviews-1.1.2 → pycordviews-1.1.4}/pyproject.toml +0 -0
  30. {pycordviews-1.1.2 → pycordviews-1.1.4}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PycordViews
3
- Version: 1.1.2
3
+ Version: 1.1.4
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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PycordViews
3
- Version: 1.1.2
3
+ Version: 1.1.4
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)
@@ -8,7 +8,6 @@ PycordViews.egg-info/dependency_links.txt
8
8
  PycordViews.egg-info/requires.txt
9
9
  PycordViews.egg-info/top_level.txt
10
10
  pycordViews/__init__.py
11
- pycordViews/typeViews.py
12
11
  pycordViews/menu/__init__.py
13
12
  pycordViews/menu/errors.py
14
13
  pycordViews/menu/menu.py
@@ -1,5 +1,5 @@
1
- from .typeViews import *
2
1
  from .views.easy_modified_view import EasyModifiedViews
3
2
  from .pagination.pagination_view import Pagination
4
3
  from .multibot.start_multibot import Multibot
5
4
  from .menu.selectMenu import SelectMenu
5
+ from .menu.menu import Menu, CustomSelect
@@ -1,3 +1,3 @@
1
1
  from .selectMenu import SelectMenu
2
- from .menu import Menu
2
+ from .menu import Menu, CustomSelect
3
3
  from .errors import *
@@ -0,0 +1,118 @@
1
+ from discord.components import ComponentType
2
+ from discord.ui import Select, Item
3
+ from discord import MISSING, Emoji, PartialEmoji, Interaction
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: CustomSelect = CustomSelect(menu=self, select_type=menu_type, **kwargs)
16
+ self.__selectMenu = selectmenu
17
+ self.__menu_type: ComponentType = menu_type
18
+
19
+ def set_callable(self, _callable: Union[Callable, None]) -> "Menu":
20
+ """
21
+ Add a coroutine to the menu (same function on SelectMenu class)
22
+ This coroutine can have 2 parameters (X, interaction)
23
+ """
24
+ if not isinstance(_callable, Callable):
25
+ raise NotCoroutineError(_callable)
26
+
27
+ self.__selectMenu.set_callable(self.__menu.custom_id, _callable=_callable)
28
+ return self
29
+
30
+ @property
31
+ def callable(self) -> Callable:
32
+ """
33
+ Get the current callable menu
34
+ """
35
+ return self.__selectMenu.get_callable(self.__menu.custom_id)
36
+
37
+ 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":
38
+ """
39
+ Add an option to choice.
40
+ Only from string_select type !
41
+ """
42
+ self.__is_string_select()
43
+
44
+ self.__menu.add_option(label=label, value=value, description=description, emoji=emoji, default=default)
45
+ return self
46
+
47
+ def remove_options(self, *labels: str) -> "Menu":
48
+ """
49
+ Remove an option to choice.
50
+ Only from string_select type !
51
+ :param labels: Label option name to delete
52
+ """
53
+ self.__is_string_select()
54
+
55
+ self.__menu.options = [i for i in self.__menu.options if i.label not in labels]
56
+ return self
57
+
58
+ def update_option(self, 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":
59
+ """
60
+ Update option. To find the option, write her actual label in "current_label" option.
61
+ Only from string_select type !
62
+ :param current_label: The current label option to edit
63
+ """
64
+ self.__is_string_select()
65
+
66
+ for option in self.__menu.options:
67
+ if option.label == current_label:
68
+ option.label = new_label if new_label is not None else option.label
69
+ option.value = value if value is not None else option.value
70
+ option.description = description if description is not None else option.description
71
+ option.default = default if default is not None else option.default
72
+ option.emoji = emoji if emoji is not None else option.emoji
73
+ break
74
+ return self
75
+
76
+ def __is_string_select(self) -> None:
77
+ """
78
+ Check if the menu is a string_select
79
+ :raise: ComponentTypeError
80
+ """
81
+ if self.__menu.type != ComponentType.string_select:
82
+ raise ComponentTypeError()
83
+
84
+ @property
85
+ def component(self) -> Select:
86
+ """
87
+ Get the component
88
+ """
89
+ return self.__menu
90
+
91
+ @property
92
+ def selectmenu(self) -> "SelectMenu":
93
+ """
94
+ Get the selectMenu
95
+ """
96
+ return self.__selectMenu
97
+
98
+ class CustomSelect(Select):
99
+ """
100
+ Subclass of Select discord Class to use some SelectMenu functions
101
+ """
102
+
103
+ def __init__(self, menu: Menu, select_type: ComponentType, *items: Item, **kwargs):
104
+ super().__init__(select_type=select_type, *items, **kwargs)
105
+ self.__menu: Menu = menu
106
+
107
+ async def update(self):
108
+ """
109
+ Bridge to SelectMenu update function
110
+ """
111
+ return await self.__menu.selectmenu.update()
112
+
113
+ @property
114
+ def get_view(self) -> "EasyModifiedViews":
115
+ """
116
+ Bridge to SelectMenu get_view property
117
+ """
118
+ return self.__menu.selectmenu.get_view
@@ -1,7 +1,8 @@
1
+
1
2
  from ..views.easy_modified_view import EasyModifiedViews
2
3
  from .menu import Menu
3
4
 
4
- from typing import Union, Callable
5
+ from typing import Union, Callable, Any
5
6
  from discord.components import ComponentType
6
7
  from discord import ChannelType, Member, TextChannel, ApplicationContext
7
8
 
@@ -89,7 +90,7 @@ class SelectMenu:
89
90
  global function to add a Select component
90
91
  """
91
92
  menu = Menu(component_type,
92
- self.__select_menu,
93
+ self,
93
94
  **{'custom_id': custom_id, 'placeholder': placeholder, 'min_values': min_values,
94
95
  'max_values': max_values, 'disabled': disabled, 'row': row, 'channel_types': channel_types})
95
96
 
@@ -97,24 +98,35 @@ class SelectMenu:
97
98
 
98
99
  return menu
99
100
 
100
- def set_callable(self, *custom_ids: str, _callable : Callable):
101
+ def set_callable(self, *custom_ids: str, _callable: Union[Callable, None]) -> "SelectMenu":
101
102
  """
102
- Set a callable for the menu associated with the custom_id
103
+ Set a callable for the menu associated with custom_ids
103
104
  :param custom_ids: IDs to menus
105
+ :param _callable: The coroutine to set for all menus
104
106
  """
105
107
  self.__select_menu.set_callable(*custom_ids, _callable=_callable)
108
+ return self
106
109
 
107
- async def respond(self, ctx: ApplicationContext, *args, **kwargs) -> None:
110
+ async def respond(self, ctx: ApplicationContext, *args, **kwargs) -> Any:
108
111
  """
109
112
  Respond at the ApplicationContext
110
113
  """
111
- await self.__select_menu.respond(ctx=ctx, *args, view=self.__select_menu, **kwargs)
114
+ return await self.__select_menu.respond(ctx=ctx, *args, view=self.__select_menu, **kwargs)
112
115
 
113
- async def send(self, target: Union[Member, TextChannel], *args, **kwargs) -> None:
116
+ async def send(self, target: Union[Member, TextChannel], *args, **kwargs) -> Any:
114
117
  """
115
118
  Send at the target
116
119
  """
117
- await self.__select_menu.send(target=target, *args, view=self.__select_menu, **kwargs)
120
+ return await self.__select_menu.send(target=target, *args, view=self.__select_menu, **kwargs)
121
+
122
+ async def update(self):
123
+ """
124
+ Update the message.
125
+ If the command doesn't have been respond, nothing happened.
126
+ """
127
+ if self.get_view.message is None:
128
+ return
129
+ await self.__select_menu.update_items(*self.get_view.items)
118
130
 
119
131
  @property
120
132
  def get_view(self) -> EasyModifiedViews:
@@ -122,3 +134,10 @@ class SelectMenu:
122
134
  Get the current view
123
135
  """
124
136
  return self.__select_menu
137
+
138
+ def get_callable(self, custom_id: str) -> Union[Callable, None]:
139
+ """
140
+ Get the callable UI
141
+ :param custom_id: UI ID
142
+ """
143
+ return self.__select_menu.get_callable(custom_id)
@@ -23,6 +23,7 @@ class Pagination:
23
23
 
24
24
  self.__view.add_items(Button(label='⏮', row=0, custom_id='back+', style=ButtonStyle.blurple))
25
25
  self.__view.add_items(Button(label='◀', row=0, custom_id='back', style=ButtonStyle.blurple))
26
+ self.__view.add_items(Button(label='None', row=0, custom_id='counter', style=ButtonStyle.gray, disabled=True))
26
27
  self.__view.add_items(Button(label='▶', row=0, custom_id='forward', style=ButtonStyle.blurple))
27
28
  self.__view.add_items(Button(label='⏭', row=0, custom_id='forward+', style=ButtonStyle.blurple))
28
29
  self.__view.set_callable('back+', 'back', 'forward', 'forward+', _callable=self.__turn_page)
@@ -30,7 +31,7 @@ class Pagination:
30
31
  self.__pages: list[tuple[tuple, dict]] = []
31
32
  self.__current_page: int = 0
32
33
 
33
- def add_page(self, *args, **kwargs) -> None:
34
+ def add_page(self, *args, **kwargs) -> "Pagination":
34
35
  """
35
36
  Adds a page (in a list) as if this function directly sent the message
36
37
  Pages are just modified and not reset ! Don't forget to disable embeds or content if the page don't need this.
@@ -38,8 +39,10 @@ class Pagination:
38
39
  add_page(content="my message", embeds=[embed1, embed2], ...)
39
40
  """
40
41
  self.__pages.append((args, kwargs))
42
+ self.__view.get_ui('counter').label = f"{self.__current_page+1}/{len(self.__pages)}"
43
+ return self
41
44
 
42
- def delete_pages(self, *page_numbers: Union[str, int]):
45
+ def delete_pages(self, *page_numbers: Union[str, int]) -> "Pagination":
43
46
  """
44
47
  Deletes pages in the order in which they were added
45
48
  **Start to 0 !**
@@ -53,6 +56,8 @@ class Pagination:
53
56
  raise PageNumberNotFound(page_number)
54
57
 
55
58
  del self.__pages[page_number]
59
+ self.__view.get_ui('counter').label = f"{self.__current_page+1}/{len(self.__pages)}"
60
+ return self
56
61
 
57
62
  async def __turn_page(self, button, interaction: Interaction):
58
63
  """
@@ -79,11 +84,14 @@ class Pagination:
79
84
  elif interaction.custom_id == 'forward+': # Go to the last page
80
85
  self.__current_page = page_count-1
81
86
 
87
+ self.__view.get_ui('counter').label = f"{self.__current_page + 1}/{len(self.__pages)}"
82
88
 
83
89
  await interaction.message.edit(
84
90
 
85
91
  *self.__pages[self.__current_page][0],
86
92
 
93
+ view=self.get_view,
94
+
87
95
  **self.__pages[self.__current_page][1]
88
96
 
89
97
  )
@@ -91,18 +99,18 @@ class Pagination:
91
99
  # Acknowledge the interaction
92
100
  await interaction.response.defer(invisible=True)
93
101
 
94
- async def send(self, target: Union[Member, TextChannel]) -> None:
102
+ async def send(self, target: Union[Member, TextChannel]) -> Any:
95
103
  """
96
104
  Send pagination without introduction message.
97
105
  :param target: The member or channel to send the pagination
98
106
  """
99
- await self.__view.send(ctx=target, *self.__pages[0][0], **self.__pages[0][1], view=self.get_view)
107
+ return await self.__view.send(ctx=target, *self.__pages[0][0], **self.__pages[0][1], view=self.get_view)
100
108
 
101
- async def respond(self, ctx: ApplicationContext) -> None:
109
+ async def respond(self, ctx: ApplicationContext) -> Any:
102
110
  """
103
111
  Respond to the command call
104
112
  """
105
- await self.__view.respond(ctx=ctx, *self.__pages[0][0], **self.__pages[0][1], view=self.get_view)
113
+ return await self.__view.respond(ctx=ctx, *self.__pages[0][0], **self.__pages[0][1], view=self.get_view)
106
114
 
107
115
  @property
108
116
  def get_view(self) -> EasyModifiedViews:
@@ -115,5 +123,6 @@ class Pagination:
115
123
  def get_page(self) -> int:
116
124
  """
117
125
  Get the number of showed page
126
+ (start to 0)
118
127
  """
119
128
  return self.__current_page
@@ -1,10 +1,14 @@
1
+ from __future__ import annotations
1
2
  from discord import Interaction, ApplicationContext, Message, Member, TextChannel
2
3
  from discord.ui import View, Item
3
- from typing import Union, Callable, Iterable
4
+ from typing import Union, Callable, TYPE_CHECKING
4
5
 
5
- from ..typeViews import T_views
6
6
  from .errors import CustomIDNotFound
7
7
 
8
+ if TYPE_CHECKING:
9
+ from ..menu.selectMenu import SelectMenu
10
+ from ..pagination.pagination_view import Pagination
11
+
8
12
 
9
13
  class EasyModifiedViews(View):
10
14
  """
@@ -21,7 +25,7 @@ class EasyModifiedViews(View):
21
25
  super().__init__(*items, timeout=timeout)
22
26
  self.__timeout: Union[float, None] = timeout
23
27
  self.__disabled_on_timeout: bool = disabled_on_timeout
24
- self.__callback: dict[str, dict[str, Union[Callable[[Interaction], None], T_views]]] = {}
28
+ self.__callback: dict[str, dict[str, Union[Callable[[Interaction], None], Item]]] = {}
25
29
  self.__ctx: Union[Message, Interaction] = None
26
30
 
27
31
  def __check_custom_id(self, custom_id: str) -> None:
@@ -46,19 +50,25 @@ class EasyModifiedViews(View):
46
50
  self.__ctx = await target.send(*args, **kwargs)
47
51
 
48
52
  def add_items(self,
49
- *items: T_views) -> "EasyModifiedViews":
53
+ *items: Union[Item, SelectMenu, Pagination]) -> "EasyModifiedViews":
50
54
  """
51
55
  Add all items in the View.
52
56
  """
53
57
 
54
58
  for ui in items:
55
59
 
56
- self.__callback[ui.custom_id] = {'ui': ui, 'func': None}
57
- self.add_item(ui)
60
+ if type(ui).__name__ in ('SelectMenu', 'Pagination'):
61
+ for item in ui.get_view.items:
62
+ self.add_items(item)
63
+ self.set_callable(item.custom_id, _callable=ui.get_callable(item.custom_id))
64
+
65
+ else:
66
+ self.__callback[ui.custom_id] = {'ui': ui, 'func': None}
67
+ self.add_item(ui)
58
68
 
59
69
  return self
60
70
 
61
- async def update_items(self, *items: T_views) -> "EasyModifiedViews":
71
+ async def update_items(self, *items: Item) -> "EasyModifiedViews":
62
72
  """
63
73
  Update all views.
64
74
  Append items if custom_ids not in the view
@@ -67,7 +77,6 @@ class EasyModifiedViews(View):
67
77
  """
68
78
 
69
79
  for item in items:
70
-
71
80
  try:
72
81
  self.__check_custom_id(item.custom_id)
73
82
  self.__callback[item.custom_id]['ui'] = item
@@ -128,6 +137,14 @@ class EasyModifiedViews(View):
128
137
 
129
138
  self.__callback[custom_id]['func'] = _callable
130
139
 
140
+ def get_callable(self, custom_id: str) -> Union[Callable, None]:
141
+ """
142
+ Get the callable UI
143
+ :param custom_id: UI ID
144
+ """
145
+ self.__check_custom_id(custom_id)
146
+ return self.__callback[custom_id]['func']
147
+
131
148
  async def interaction_check(self, interaction: Interaction) -> bool:
132
149
  """
133
150
  Func to apply items
@@ -243,25 +260,26 @@ class EasyModifiedViews(View):
243
260
  """
244
261
  Update the View on the attached message.
245
262
  """
246
- try:
263
+ if self.is_finished():
264
+ return
247
265
 
248
- if self.message:
249
- await self.message.edit(view=self)
266
+ if self.message:
267
+ await self.message.edit(view=self)
250
268
 
251
- else:
252
- await self.__ctx.edit(view=self)
269
+ elif self.__ctx:
270
+ await self.__ctx.edit(view=self)
253
271
 
254
- except:
255
- pass
272
+ else:
273
+ return
256
274
 
257
275
  @property
258
- def get_uis(self) -> list[T_views]:
276
+ def get_uis(self) -> list[Item]:
259
277
  """
260
278
  Get all uis in the view
261
279
  """
262
280
  return [i['ui'] for i in self.__callback.values()]
263
281
 
264
- def get_ui(self, custom_id: str) -> T_views:
282
+ def get_ui(self, custom_id: str) -> Item:
265
283
  """
266
284
  Get an ui in the view
267
285
  :raise: CustomIDNotFound
@@ -270,4 +288,8 @@ class EasyModifiedViews(View):
270
288
  return self.__callback[custom_id]['ui']
271
289
 
272
290
  def __str__(self):
273
- return str(self.__callback)
291
+ return str(self.__callback)
292
+
293
+ @property
294
+ def items(self) -> tuple[Item]:
295
+ return tuple([i['ui'] for i in self.__callback.values()])
@@ -5,7 +5,7 @@ with open("README.md") as file:
5
5
 
6
6
  setup(
7
7
  name="PycordViews",
8
- version="1.1.2",
8
+ version="1.1.4",
9
9
  url="https://github.com/BOXERRMD/Py-cord_Views",
10
10
  author="Chronos (alias BOXERRMD)",
11
11
  author_email="vagabonwalybi@gmail.com",
@@ -1,57 +0,0 @@
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
- """
@@ -1,4 +0,0 @@
1
- from typing import TypeVar
2
- from discord.ui import Button, Select, Modal
3
-
4
- T_views = TypeVar('T_views', Button, Select)
File without changes
File without changes
File without changes
File without changes