1
1
import typing
2
2
from asyncio import TimeoutError
3
3
4
- from discord import Embed , Message , HTTPException , InvalidArgument
4
+ from discord import Embed , Message , HTTPException , InvalidArgument , Reaction
5
5
from discord .ext import commands
6
6
7
+ from core .models import User
8
+
7
9
8
10
class PaginatorSession :
9
11
"""
10
- Class that interactively paginates a set of embeds
12
+ Class that interactively paginates a list of `Embed`.
11
13
12
14
Parameters
13
- ------------
14
- ctx: Context
15
+ ----------
16
+ ctx : Context
17
+ The context of the command.
18
+ timeout : float
19
+ How long to wait for before the session closes.
20
+ embeds : List[Embed]
21
+ A list of entries to paginate.
22
+ edit_footer : bool, optional
23
+ Whether to set the footer.
24
+ Defaults to `True`.
25
+
26
+ Attributes
27
+ ----------
28
+ ctx : Context
15
29
The context of the command.
16
- timeout:
17
- How long to wait for before the session closes
18
- embeds: List[Embed]
30
+ timeout : float
31
+ How long to wait for before the session closes.
32
+ embeds : List[Embed]
19
33
A list of entries to paginate.
34
+ running : bool
35
+ Whether the paginate session is running.
36
+ base : Message
37
+ The `Message` of the `Embed`.
38
+ current : int
39
+ The current page number.
40
+ reaction_map : Dict[str, meth]
41
+ A mapping for reaction to method.
20
42
21
- Methods
22
- -------
23
- add_page:
24
- Add an embed to paginate
25
- run:
26
- Run the interactive session
27
- close:
28
- Forcefully destroy a session
29
43
"""
30
44
31
45
def __init__ (self , ctx : commands .Context , * embeds , ** options ):
@@ -52,12 +66,28 @@ def __init__(self, ctx: commands.Context, *embeds, **options):
52
66
icon_url = embed .footer .icon_url )
53
67
54
68
def add_page (self , embed : Embed ) -> None :
69
+ """
70
+ Add a `Embed` page.
71
+
72
+ Parameters
73
+ ----------
74
+ embed : Embed
75
+ The `Embed` to add.
76
+ """
55
77
if isinstance (embed , Embed ):
56
78
self .embeds .append (embed )
57
79
else :
58
80
raise TypeError ('Page must be an Embed object.' )
59
81
60
82
async def create_base (self , embed : Embed ) -> None :
83
+ """
84
+ Create a base `Message`.
85
+
86
+ Parameters
87
+ ----------
88
+ embed : Embed
89
+ The `Embed` to fill the base `Message`.
90
+ """
61
91
self .base = await self .ctx .send (embed = embed )
62
92
63
93
if len (self .embeds ) == 1 :
@@ -71,6 +101,14 @@ async def create_base(self, embed: Embed) -> None:
71
101
await self .base .add_reaction (reaction )
72
102
73
103
async def show_page (self , index : int ) -> None :
104
+ """
105
+ Show a page by page number.
106
+
107
+ Parameters
108
+ ----------
109
+ index : int
110
+ The index of the page.
111
+ """
74
112
if not 0 <= index < len (self .embeds ):
75
113
return
76
114
@@ -82,12 +120,33 @@ async def show_page(self, index: int) -> None:
82
120
else :
83
121
await self .create_base (page )
84
122
85
- def react_check (self , reaction , user ) -> bool :
86
- return reaction .message .id == self .base .id and \
87
- user .id == self .ctx .author .id and \
88
- reaction .emoji in self .reaction_map .keys ()
123
+ def react_check (self , reaction : Reaction , user : User ) -> bool :
124
+ """
125
+
126
+ Parameters
127
+ ----------
128
+ reaction : Reaction
129
+ The `Reaction` object of the reaction.
130
+ user : User
131
+ The `User` or `Member` object of who sent the reaction.
132
+
133
+ Returns
134
+ -------
135
+ bool
136
+ """
137
+ return (reaction .message .id == self .base .id and
138
+ user .id == self .ctx .author .id and
139
+ reaction .emoji in self .reaction_map .keys ())
89
140
90
141
async def run (self ) -> typing .Optional [Message ]:
142
+ """
143
+ Starts the pagination session.
144
+
145
+ Returns
146
+ -------
147
+ Optional[Message]
148
+ If it's closed before running ends.
149
+ """
91
150
if not self .running :
92
151
await self .show_page (0 )
93
152
while self .running :
@@ -108,15 +167,32 @@ async def run(self) -> typing.Optional[Message]:
108
167
pass
109
168
110
169
async def previous_page (self ) -> None :
111
- """Go to the previous page."""
170
+ """
171
+ Go to the previous page.
172
+ """
112
173
await self .show_page (self .current - 1 )
113
174
114
175
async def next_page (self ) -> None :
115
- """Go to the next page"""
176
+ """
177
+ Go to the next page.
178
+ """
116
179
await self .show_page (self .current + 1 )
117
180
118
181
async def close (self , delete : bool = True ) -> typing .Optional [Message ]:
119
- """Delete this embed."""
182
+ """
183
+ Closes the pagination session.
184
+
185
+ Parameters
186
+ ----------
187
+ delete : bool, optional
188
+ Whether or delete the message upon closure.
189
+ Defaults to `True`.
190
+
191
+ Returns
192
+ -------
193
+ Optional[Message]
194
+ If `delete` is `True`.
195
+ """
120
196
self .running = False
121
197
122
198
try :
@@ -133,9 +209,13 @@ async def close(self, delete: bool = True) -> typing.Optional[Message]:
133
209
pass
134
210
135
211
async def first_page (self ) -> None :
136
- """Go to immediately to the first page"""
212
+ """
213
+ Go to the first page.
214
+ """
137
215
await self .show_page (0 )
138
216
139
217
async def last_page (self ) -> None :
140
- """Go to immediately to the last page"""
218
+ """
219
+ Go to the last page.
220
+ """
141
221
await self .show_page (len (self .embeds ) - 1 )
0 commit comments