PycordViews 1.0.0__tar.gz → 1.0.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PycordViews
3
- Version: 1.0.0
3
+ Version: 1.0.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)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: PycordViews
3
- Version: 1.0.0
3
+ Version: 1.0.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)
@@ -0,0 +1,23 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ setup.py
5
+ PycordViews.egg-info/PKG-INFO
6
+ PycordViews.egg-info/SOURCES.txt
7
+ PycordViews.egg-info/dependency_links.txt
8
+ PycordViews.egg-info/requires.txt
9
+ PycordViews.egg-info/top_level.txt
10
+ pycordViews/__init__.py
11
+ pycordViews/typeViews.py
12
+ pycordViews/pagination/__init__.py
13
+ pycordViews/pagination/errors.py
14
+ pycordViews/pagination/pagination_view.py
15
+ pycordViews/views/__init__.py
16
+ pycordViews/views/easy_modified_view.py
17
+ pycordViews/views/errors.py
18
+ pycordViews/pagination/__init__.py
19
+ pycordViews/pagination/errors.py
20
+ pycordViews/pagination/pagination_view.py
21
+ pycordViews/views/__init__.py
22
+ pycordViews/views/easy_modified_view.py
23
+ pycordViews/views/errors.py
@@ -0,0 +1,3 @@
1
+ pycordViews
2
+ pycordViews/pagination
3
+ pycordViews/views
@@ -0,0 +1,2 @@
1
+ from .pagination_view import Pagination
2
+ from .errors import PageNumberNotFound
@@ -0,0 +1,13 @@
1
+ from typing import Union
2
+
3
+ class Py_cordPagination(Exception):
4
+ """
5
+ Main class exception
6
+ """
7
+
8
+ class PageNumberNotFound(Py_cordPagination):
9
+ """
10
+ If the page number is not found
11
+ """
12
+ def __init__(self, number: Union[int, str]):
13
+ super().__init__(f"Page {number} not found !")
@@ -0,0 +1,120 @@
1
+ from ..views.easy_modified_view import EasyModifiedViews
2
+ from discord import ButtonStyle, Interaction, TextChannel, Member, ApplicationContext
3
+ from discord.ui import Button
4
+ from .errors import PageNumberNotFound
5
+
6
+ from typing import Union, Any
7
+
8
+
9
+ class Pagination:
10
+ """
11
+ Class
12
+ -------------
13
+ Allows you to easily setup a view pagination
14
+ """
15
+
16
+ def __init__(self, timeout: Union[float, None] = None, disabled_on_timeout:bool = False):
17
+ """
18
+ Initialisation for pagination
19
+ :param timeout: The time before disable items on the view
20
+ :param disabled_on_timeout: If timeout is done, disable all items
21
+ """
22
+ self.__view = EasyModifiedViews(timeout, disabled_on_timeout=disabled_on_timeout)
23
+
24
+ self.__view.add_items(Button(label='⏮', row=0, custom_id='back+', style=ButtonStyle.blurple))
25
+ self.__view.add_items(Button(label='◀', row=0, custom_id='back', style=ButtonStyle.blurple))
26
+ self.__view.add_items(Button(label='▶', row=0, custom_id='forward', style=ButtonStyle.blurple))
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)
29
+
30
+ self.__pages: list[tuple[tuple, dict]] = []
31
+ self.__current_page: int = 0
32
+
33
+ def add_page(self, *args, **kwargs) -> None:
34
+ """
35
+ Adds a page (in a list) as if this function directly sent the message
36
+ Pages are just modified and not reset ! Don't forget to disable embeds or content if the page don't need this.
37
+
38
+ add_page(content="my message", embeds=[embed1, embed2], ...)
39
+ """
40
+ self.__pages.append((args, kwargs))
41
+
42
+ def delete_pages(self, *page_numbers: Union[str, int]):
43
+ """
44
+ Deletes pages in the order in which they were added
45
+ **Start to 0 !**
46
+
47
+ delete_pages(1,2,3,...)
48
+ """
49
+ nbr_pages = len(self.__pages)-1
50
+ for page_number in page_numbers:
51
+
52
+ if page_number < 0 or page_number > nbr_pages:
53
+ raise PageNumberNotFound(page_number)
54
+
55
+ del self.__pages[page_number]
56
+
57
+ async def __turn_page(self, interaction: Interaction):
58
+ """
59
+ Turn the page when button is pressed
60
+ """
61
+ page_count = len(self.__pages)
62
+
63
+ if page_count <= 1:
64
+ await self.__view.shutdown()
65
+ await interaction.response.defer(invisible=True)
66
+ return
67
+
68
+ # Update the current page based on the button pressed
69
+
70
+ if interaction.custom_id == 'back+': # Go to the first page
71
+ self.__current_page = 0
72
+
73
+ elif interaction.custom_id == 'back': # Go to the previous page
74
+ self.__current_page = max(0, self.__current_page - 1)
75
+
76
+ elif interaction.custom_id == 'forward': # Go to the next page
77
+ self.__current_page = min(page_count-1, self.__current_page + 1)
78
+
79
+ elif interaction.custom_id == 'forward+': # Go to the last page
80
+ self.__current_page = page_count-1
81
+
82
+
83
+ await interaction.message.edit(
84
+
85
+ *self.__pages[self.__current_page][0],
86
+
87
+ **self.__pages[self.__current_page][1]
88
+
89
+ )
90
+
91
+ # Acknowledge the interaction
92
+ await interaction.response.defer(invisible=True)
93
+
94
+ async def send(self, send_to: Union[Member, TextChannel]) -> None:
95
+ """
96
+ Send pagination without introduction message.
97
+ :param send_to: The member or channel to send the pagination
98
+ """
99
+
100
+ await send_to.send(*self.__pages[0][0], **self.__pages[0][1], view=self.get_view)
101
+
102
+ async def respond(self, ctx: ApplicationContext) -> None:
103
+ """
104
+ Respond to the command call
105
+ """
106
+ await ctx.respond(*self.__pages[0][0], **self.__pages[0][1], view=self.get_view)
107
+
108
+ @property
109
+ def get_view(self) -> EasyModifiedViews:
110
+ """
111
+ Get the view of pagination
112
+ """
113
+ return self.__view
114
+
115
+ @property
116
+ def get_page(self) -> int:
117
+ """
118
+ Get the number of showed page
119
+ """
120
+ return self.__current_page
@@ -0,0 +1,2 @@
1
+ from .easy_modified_view import EasyModifiedViews
2
+ from .errors import CustomIDNotFound
@@ -0,0 +1,260 @@
1
+ from discord import Interaction, ApplicationContext, Message
2
+ from discord.ui import View, Item
3
+ from typing import Union, Callable, Coroutine, Iterable
4
+
5
+ from ..typeViews import T_views
6
+ from .errors import CustomIDNotFound
7
+
8
+
9
+ class EasyModifiedViews(View):
10
+ """
11
+ Class
12
+ -------------
13
+ Allows you to easily modify and replace an ui.
14
+ """
15
+
16
+ def __init__(self, timeout: Union[float, None] = None, disabled_on_timeout: bool = False, *items: Item):
17
+ """
18
+ Init a Class view for Discord UI
19
+ :param timeout: The time before ui disable
20
+ """
21
+ super().__init__(*items, timeout=timeout)
22
+ self.__timeout: Union[float, None] = timeout
23
+ self.__disabled_on_timeout: bool = disabled_on_timeout
24
+ self.__callback: dict[str, dict[str, Union[Callable[[Interaction], None], T_views]]] = {}
25
+ self.__ctx: Union[Message, Interaction] = None
26
+
27
+ def __check_custom_id(self, custom_id: str) -> None:
28
+ """
29
+ Check if the custom_id is alive
30
+ :param custom_id: ID to find
31
+ :raise: CustomIDNotFound
32
+ """
33
+ if custom_id not in self.__callback.keys():
34
+ raise CustomIDNotFound()
35
+
36
+ async def respond(self, ctx: ApplicationContext, *args, **kwargs) -> None:
37
+ """
38
+ Respond at the ApplicationContext
39
+ """
40
+ self.__ctx = await ctx.respond(*args, **kwargs)
41
+
42
+ def add_items(self,
43
+ *items: T_views) -> "EasyModifiedViews":
44
+ """
45
+ Add all items in the View.
46
+ custom_id REQUIRED !
47
+ """
48
+
49
+ for ui in items:
50
+
51
+ self.__callback[ui.custom_id] = {'ui': ui, 'func': None}
52
+ self.add_item(ui)
53
+
54
+ return self
55
+
56
+ async def update_items(self, *items: T_views) -> "EasyModifiedViews":
57
+ """
58
+ Update all views.
59
+ Append items if custom_ids not in the view
60
+ Update items if custom_ids in the view
61
+ :param items: items to update
62
+ """
63
+
64
+ for item in items:
65
+
66
+ try:
67
+ self.__check_custom_id(item.custom_id)
68
+ self.__callback[item.custom_id]['ui'] = item
69
+
70
+ except CustomIDNotFound:
71
+ self.add_items(item)
72
+
73
+ await self._update()
74
+ return self
75
+
76
+ def set_callable_decorator(self, custom_id: str):
77
+ """
78
+ Decorator to set up a coroutine for the item
79
+
80
+ **Interaction parameter is required in coroutine function !**
81
+
82
+ view = EasyModifiedViews(None)
83
+ view.add_view(discord.ui.Button(label='coucou', custom_id='test_ID'))
84
+
85
+ @view.set_callable_decorator(custom_id='test_ID')
86
+
87
+ async def rep(**interaction**):
88
+ await interaction.response.send_message('coucou !!!')
89
+
90
+ await ctx.respond('coucou', view=view)
91
+
92
+ :param custom_id: item ID of the view
93
+ """
94
+
95
+ def decorator(coroutine: Coroutine):
96
+ self.__check_custom_id(custom_id)
97
+
98
+ self.__callback[custom_id]['func'] = coroutine
99
+ return coroutine
100
+
101
+ return decorator
102
+
103
+ def set_callable(self, *custom_ids: str, coroutine: Coroutine):
104
+ """
105
+ set up a coroutine for items
106
+ :param custom_ids: items IDs of the view
107
+ :param coroutine: The coroutine linked
108
+
109
+ **Interaction parameter is required in coroutine function !**
110
+
111
+ view = EasyModifiedViews(None)
112
+
113
+ view.add_view(discord.ui.Button(label='coucou', custom_id='test_ID'))
114
+
115
+ async def rep(**interaction**):
116
+ await interaction.response.send_message('coucou !!!')
117
+
118
+ view.set_callable(custom_id='test_ID', coroutine=rep)
119
+ await ctx.respond('coucou', view=view)
120
+ """
121
+ for custom_id in custom_ids:
122
+ self.__check_custom_id(custom_id)
123
+
124
+ self.__callback[custom_id]['func'] = coroutine
125
+
126
+ async def interaction_check(self, interaction: Interaction) -> bool:
127
+ """
128
+ Func to apply items
129
+ """
130
+ func = self.__callback[interaction.custom_id]['func']
131
+
132
+ if func is not None:
133
+ await func(interaction)
134
+
135
+ else:
136
+ await interaction.response.defer(invisible=True)
137
+
138
+ return True
139
+
140
+ async def shutdown(self) -> None:
141
+ """
142
+ Disable all items (ui) in the view
143
+ """
144
+ self.disable_all_items()
145
+ await self._update()
146
+
147
+ async def disable_items(self, *custom_ids: str) -> None:
148
+ """
149
+ Disable partial items in the view
150
+ :param custom_ids: custom ids of all items to deactivate
151
+ """
152
+
153
+ self.disable_all_items(exclusions=[self.get_item(id_) for id_ in self.__callback.keys() if id_ not in custom_ids])
154
+ await self._update()
155
+
156
+ async def enable_items(self, *custom_ids: str) -> None:
157
+ """
158
+ Enabl partial items in the view
159
+ :param custom_ids: custom ids of all items to activate
160
+ """
161
+ self.enable_all_items(
162
+ exclusions=[self.get_item(id_) for id_ in self.__callback.keys() if id_ not in custom_ids])
163
+ await self._update()
164
+
165
+ async def full_enable_items(self) -> None:
166
+ """
167
+ Enable all items in the view
168
+ """
169
+ self.enable_all_items()
170
+ await self._update()
171
+
172
+
173
+ async def switch_status_items(self):
174
+ """
175
+ Switch status for all items
176
+ Enable -> Disable
177
+ Disable -> Enable
178
+ """
179
+
180
+ for key, in self.__callback.keys():
181
+ self.__callback[key]['ui'].disabled = not self.__callback[key]['ui'].disabled
182
+
183
+ await self._update()
184
+
185
+
186
+ def is_items_disabled(self, *custom_ids: str) -> bool:
187
+ """
188
+ Return True if all items are disabled
189
+ """
190
+
191
+ for custom_id in custom_ids:
192
+ self.__check_custom_id(custom_id)
193
+ if not self.__callback[custom_id]['ui'].disabled:
194
+ return False
195
+
196
+ return True
197
+
198
+
199
+ def is_items_enabled(self, *custom_ids: str) -> bool:
200
+ """
201
+ Return True il aff items are enabled
202
+ """
203
+
204
+ for custom_id in custom_ids:
205
+ self.__check_custom_id(custom_id)
206
+ if self.__callback[custom_id]['ui'].disabled:
207
+ return False
208
+
209
+ return True
210
+
211
+
212
+ async def delete_items(self, clear_all: bool = False, *custom_ids: str) -> None:
213
+ """
214
+ Delete an item on the view
215
+ :param custom_ids: IDs of items to delete
216
+ :param clear_all: Clear all items in the view
217
+ :raise: CustomIDNotFound
218
+ """
219
+ if clear_all:
220
+ self.clear_items()
221
+
222
+ else:
223
+
224
+ for custom_id in custom_ids:
225
+ self.__check_custom_id(custom_id)
226
+ self.remove_item(self.get_item(custom_id))
227
+
228
+ await self._update()
229
+
230
+ def on_timeout(self) -> None:
231
+ """
232
+ Called if timeout view is finished
233
+ """
234
+ if self.__disabled_on_timeout:
235
+ self.shutdown()
236
+
237
+ async def _update(self) -> None:
238
+ """
239
+ Update the View on the attached message.
240
+ """
241
+ if self.message:
242
+ await self.message.edit(view=self)
243
+
244
+ else:
245
+ await self.__ctx.edit(view=self)
246
+
247
+ @property
248
+ def get_uis(self) -> list[T_views]:
249
+ """
250
+ Get all uis in the view
251
+ """
252
+ return [i['ui'] for i in self.__callback.values()]
253
+
254
+ def get_ui(self, custom_id: str) -> T_views:
255
+ """
256
+ Get an ui in the view
257
+ :raise: CustomIDNotFound
258
+ """
259
+ self.__check_custom_id(custom_id)
260
+ return self.__callback[custom_id]['ui']
@@ -0,0 +1,9 @@
1
+ class Py_cordEasyModifiedViews(Exception):
2
+ """
3
+ Main class exception
4
+ """
5
+
6
+
7
+ class CustomIDNotFound(Py_cordEasyModifiedViews):
8
+ def __init__(self):
9
+ super().__init__(f"custom_id not found !")
@@ -5,7 +5,7 @@ with open("README.md") as file:
5
5
 
6
6
  setup(
7
7
  name="PycordViews",
8
- version="1.0.0",
8
+ version="1.0.1",
9
9
  url="https://github.com/BOXERRMD/Py-cord_Views",
10
10
  author="Chronos (alias BOXERRMD)",
11
11
  author_email="vagabonwalybi@gmail.com",
@@ -27,6 +27,6 @@ setup(
27
27
  install_requires=[
28
28
  "py-cord==2.6.1"
29
29
  ],
30
- packages=['pycordViews'],
30
+ packages=['pycordViews', 'pycordViews/pagination', 'pycordViews/views'],
31
31
  python_requires='>=3.9'
32
32
  )
@@ -1,11 +0,0 @@
1
- LICENSE
2
- README.md
3
- pyproject.toml
4
- setup.py
5
- PycordViews.egg-info/PKG-INFO
6
- PycordViews.egg-info/SOURCES.txt
7
- PycordViews.egg-info/dependency_links.txt
8
- PycordViews.egg-info/requires.txt
9
- PycordViews.egg-info/top_level.txt
10
- pycordViews/__init__.py
11
- pycordViews/typeViews.py
@@ -1 +0,0 @@
1
- pycordViews
File without changes
File without changes
File without changes
File without changes