gitscope
← marzneshin / v0.1.4 / app/telegram/utils/keyboard.py
https://dev.kronoz.win/r/marzneshin.git
app/telegram/utils/keyboard.py · Python
Blame Raw
  1from datetime import datetime as dt
  2from itertools import islice
  3from typing import Literal, Dict, List
  4
  5from telebot import types  # noqa
  6
  7from app.utils.system import readable_size
  8
  9
 10def chunk_dict(data: dict, size: int = 2):
 11    it = iter(data)
 12    for i in range(0, len(data), size):
 13        yield {k: data[k] for k in islice(it, size)}
 14
 15
 16class BotKeyboard:
 17
 18    @staticmethod
 19    def main_menu():
 20        keyboard = types.InlineKeyboardMarkup()
 21        keyboard.add(
 22            types.InlineKeyboardButton(text='🔁 System Info', callback_data='system'),
 23            types.InlineKeyboardButton(text='♻️ Restart Xray', callback_data='restart'))
 24        keyboard.add(
 25            types.InlineKeyboardButton(text='👥 Users', callback_data='users:1'),
 26            types.InlineKeyboardButton(text='✏️ Edit All Users', callback_data='edit_all'))
 27        #keyboard.add(
 28        #    types.InlineKeyboardButton(text='➕ Create User From Template', callback_data='template_add_user'))
 29        keyboard.add(
 30            types.InlineKeyboardButton(text='➕ Create User', callback_data='add_user'))
 31        return keyboard
 32
 33
 34    @staticmethod
 35    def edit_all_menu():
 36        keyboard = types.InlineKeyboardMarkup()
 37        keyboard.add(
 38            types.InlineKeyboardButton(text='🗑 Delete Expired', callback_data='delete_expired'),
 39            types.InlineKeyboardButton(text='🗑 Delete Limited', callback_data='delete_limited'))
 40        keyboard.add(
 41            types.InlineKeyboardButton(text='🔋 Data (➕|➖)', callback_data='add_data'),
 42            types.InlineKeyboardButton(text='📅 Time (➕|➖)', callback_data='add_time'))
 43        #keyboard.add(
 44        #    types.InlineKeyboardButton(text='➕ Add Inbound', callback_data='inbound_add'),
 45        #    types.InlineKeyboardButton(text='➖ Remove Inbound', callback_data='inbound_remove'))
 46        keyboard.add(types.InlineKeyboardButton(text='🔙 Back', callback_data='cancel'))
 47        return keyboard
 48
 49
 50    #@staticmethod
 51    #def inbounds_menu(action, inbounds):
 52    #    keyboard = types.InlineKeyboardMarkup()
 53    #    for inbound in inbounds:
 54    #        keyboard.add(types.InlineKeyboardButton(text=inbound, callback_data=f'confirm_{action}:{inbound}'))
 55    #    keyboard.add(types.InlineKeyboardButton(text='🔙 Back', callback_data='cancel'))
 56    #    return keyboard
 57
 58
 59    @staticmethod
 60    def random_username(template_id: str = ''):
 61        keyboard = types.InlineKeyboardMarkup()
 62
 63        keyboard.add(types.InlineKeyboardButton(
 64                text='🔡 Random Username',
 65                callback_data=f'random:{template_id}'))
 66        keyboard.add(types.InlineKeyboardButton(
 67                text='🔙 Cancel',
 68                callback_data='cancel'))
 69        return keyboard
 70
 71
 72    @staticmethod
 73    def user_menu(user_info, with_back: bool = True, page: int = 1, note: bool = False):
 74        keyboard = types.InlineKeyboardMarkup()
 75        keyboard.add(
 76            types.InlineKeyboardButton(
 77                text='❌ Disable' if user_info['status'] == 'active' else '✅ Activate',
 78                callback_data=f"{'suspend' if user_info['status'] == 'active' else 'activate'}:{user_info['username']}"
 79            ),
 80            types.InlineKeyboardButton(
 81                text='🗑 Delete',
 82                callback_data=f"delete:{user_info['username']}"
 83            ),
 84        )
 85        if note:
 86            keyboard.add(
 87                types.InlineKeyboardButton(
 88                    text='🚫 Revoke Sub',
 89                    callback_data=f"revoke_sub:{user_info['username']}"),
 90                types.InlineKeyboardButton(
 91                    text='✏️ Edit',
 92                    callback_data=f"edit:{user_info['username']}"))
 93            keyboard.add(
 94                types.InlineKeyboardButton(
 95                    text='📝 Edit Note',
 96                    callback_data=f"edit_note:{user_info['username']}"),
 97                types.InlineKeyboardButton(
 98                    text='📡 Links',
 99                    callback_data=f"links:{user_info['username']}"))
100        else:
101            keyboard.add(
102                types.InlineKeyboardButton(
103                    text='📡 Links',
104                    callback_data=f"links:{user_info['username']}"),
105                types.InlineKeyboardButton(
106                    text='✏️ Edit',
107                    callback_data=f"edit:{user_info['username']}"))
108        keyboard.add(
109            types.InlineKeyboardButton(
110                text='🔁 Reset usage',
111                callback_data=f"reset_usage:{user_info['username']}"
112            ),
113            types.InlineKeyboardButton(
114                text='🔋 Charge',
115                callback_data=f"charge:{user_info['username']}"
116            )
117        )
118        if with_back:
119            keyboard.add(
120                types.InlineKeyboardButton(
121                    text='🔙 Back',
122                    callback_data=f'users:{page}'
123                )
124            )
125        return keyboard
126
127    @staticmethod
128    def show_links(username: str):
129        keyboard = types.InlineKeyboardMarkup()
130
131        keyboard.add(
132            types.InlineKeyboardButton(
133                text="🖼 QR code",
134                callback_data=f'genqr:{username}'
135            )
136        )
137        keyboard.add(
138            types.InlineKeyboardButton(
139                text='🔙 Back',
140                callback_data=f'user:{username}'
141            )
142        )
143        return keyboard
144
145
146    @staticmethod
147    def subscription_page(sub_url: str):
148        keyboard = types.InlineKeyboardMarkup()
149        if sub_url[:4] == 'http':
150            keyboard.add(types.InlineKeyboardButton(
151                text='🚀 Subscription Page',
152                url=sub_url))
153        return keyboard
154
155
156    @staticmethod
157    def confirm_action(action: str, username: str = None):
158        keyboard = types.InlineKeyboardMarkup()
159        keyboard.add(
160            types.InlineKeyboardButton(
161                text='Yes',
162                callback_data=f"{action}:{username}"
163            ),
164            types.InlineKeyboardButton(
165                text='No',
166                callback_data=f"cancel"
167            )
168        )
169        return keyboard
170
171    @staticmethod
172    def inline_cancel_action(callback_data: str = "cancel"):
173        keyboard = types.InlineKeyboardMarkup()
174        keyboard.add(
175            types.InlineKeyboardButton(
176                text="🔙 Cancel",
177                callback_data=callback_data
178            )
179        )
180        return keyboard
181
182    @staticmethod
183    def user_list(users: list, page: int, total_pages: int):
184        keyboard = types.InlineKeyboardMarkup()
185        if len(users) >= 2:
186            users = [p for p in users]
187            users = [users[i:i + 2] for i in range(0, len(users), 2)]
188        else:
189            users = [users]
190        for user in users:
191            row = []
192            for p in user:
193                status = {
194                    'active': '✅',
195                    'expired': '🕰',
196                    'limited': '📵',
197                    'disabled': '❌'
198                }
199                row.append(types.InlineKeyboardButton(
200                    text=f"{p.username} ({status[p.status]})",
201                    callback_data=f'user:{p.username}:{page}'
202                ))
203            keyboard.row(*row)
204        # if there is more than one page
205        if total_pages > 1:
206            if page > 1:
207                keyboard.add(
208                    types.InlineKeyboardButton(
209                        text="⬅️ Previous",
210                        callback_data=f'users:{page - 1}'
211                    )
212                )
213            if page < total_pages:
214                keyboard.add(
215                    types.InlineKeyboardButton(
216                        text="➡️ Next",
217                        callback_data=f'users:{page + 1}'
218                    )
219                )
220        keyboard.add(
221            types.InlineKeyboardButton(
222                text='🔙 Back',
223                callback_data='cancel'
224            )
225        )
226        return keyboard
227
228    @staticmethod
229    def select_services(services,
230                        selected_services: List[int],
231                        action: Literal["edit", "create"],
232                        username: str = None,
233                        data_limit: float = None,
234                        expire_date: dt = None):
235        
236        keyboard = types.InlineKeyboardMarkup()
237
238        if action == "edit":
239            keyboard.add(
240                types.InlineKeyboardButton(
241                    text="⚠️ Data Limit:",
242                    callback_data=f"help_edit"
243                )
244            )
245            keyboard.add(
246                types.InlineKeyboardButton(
247                    text=f"{readable_size(data_limit) if data_limit else 'Unlimited'}",
248                    callback_data=f"help_edit"
249                ),
250                types.InlineKeyboardButton(
251                    text="✏️ Edit",
252                    callback_data=f"edit_user:{username}:data"
253                )
254            )
255            keyboard.add(
256                types.InlineKeyboardButton(
257                    text="📅 Expire Date:",
258                    callback_data=f"help_edit"
259                )
260            )
261            keyboard.add(
262                types.InlineKeyboardButton(
263                    text=f"{expire_date.strftime('%Y-%m-%d') if expire_date else 'Never'}",
264                    callback_data=f"help_edit"
265                ),
266                types.InlineKeyboardButton(
267                    text="✏️ Edit",
268                    callback_data=f"edit_user:{username}:expire"
269                )
270            )
271        for s in services:
272            keyboard.add(
273                    types.InlineKeyboardButton(
274                        text=f"🌐 {s.name} {'✅' if s.id in selected_services else '❌'}",
275                        callback_data=f"switch_service:{s.id}:{action}"
276                        )
277                    )
278        keyboard.add(
279            types.InlineKeyboardButton(
280                text='Done',
281                callback_data='edit_user_done' if action == "edit" else 'add_user_done'
282            )
283        )
284        keyboard.add(
285            types.InlineKeyboardButton(
286                text='Cancel',
287                callback_data=f'user:{username}' if action == "edit" else 'cancel'
288            )
289        )
290
291        return keyboard