# ═══════════════════════════════════════════════════════════════ # Keys Pagination System for Owner & Admin Bots # Add this code to nitro_system/bots.py # ═══════════════════════════════════════════════════════════════ # CONFIGURATION KEYS_PER_PAGE = 8 # عدد المفاتيح في كل صفحة # ═══════════════════════════════════════════════════════════════ # 1. Add to LANG["ar"] dictionary: # ═══════════════════════════════════════════════════════════════ "page_info": "📄 صفحة {current} من {total}", "next_page": "التالي ➡️", "prev_page": "⬅️ السابق", "no_more_pages": "لا توجد صفحات أخرى", # ═══════════════════════════════════════════════════════════════ # 2. Add to LANG["en"] dictionary: # ═══════════════════════════════════════════════════════════════ "page_info": "📄 Page {current} of {total}", "next_page": "Next ➡️", "prev_page": "⬅️ Previous", "no_more_pages": "No more pages", # ═══════════════════════════════════════════════════════════════ # 3. Add to LANG["ru"] dictionary: # ═══════════════════════════════════════════════════════════════ "page_info": "📄 Страница {current} из {total}", "next_page": "Далее ➡️", "prev_page": "⬅️ Назад", "no_more_pages": "Больше нет страниц", # ═══════════════════════════════════════════════════════════════ # 4. Helper Functions - Add these BEFORE owner_callback function: # ═══════════════════════════════════════════════════════════════ def paginate_list(items, page=1, per_page=KEYS_PER_PAGE): """Paginate a list of items""" total_items = len(items) total_pages = (total_items + per_page - 1) // per_page # Ceiling division if page < 1: page = 1 if page > total_pages and total_pages > 0: page = total_pages start_idx = (page - 1) * per_page end_idx = start_idx + per_page return { 'items': items[start_idx:end_idx], 'page': page, 'total_pages': total_pages, 'total_items': total_items, 'has_next': page < total_pages, 'has_prev': page > 1 } def create_pagination_keyboard(callback_prefix, page, total_pages, back_callback, lang='en'): """Create pagination keyboard buttons""" kb = [] # Navigation buttons nav_row = [] if page > 1: nav_row.append(InlineKeyboardButton( LANG[lang]["prev_page"], callback_data=f'{callback_prefix}_page_{page-1}' )) # Page info nav_row.append(InlineKeyboardButton( LANG[lang]["page_info"].format(current=page, total=total_pages), callback_data='page_info' )) if page < total_pages: nav_row.append(InlineKeyboardButton( LANG[lang]["next_page"], callback_data=f'{callback_prefix}_page_{page+1}' )) if nav_row: kb.append(nav_row) # Back button kb.append([InlineKeyboardButton(LANG[lang]["back"], callback_data=back_callback)]) return kb # ═══════════════════════════════════════════════════════════════ # 5. OWNER BOT - Replace 'o_all_keys' handler in owner_callback: # ═══════════════════════════════════════════════════════════════ elif q.data == 'o_all_keys' or q.data.startswith('o_all_keys_page_'): # Extract page number page = 1 if q.data.startswith('o_all_keys_page_'): try: page = int(q.data.split('_')[-1]) except: page = 1 lkeys = load_license_keys() all_keys = [(k, rec) for k, rec in lkeys.items() if rec.get("status") in ("pending", "active")] if not all_keys: msg = LANG[lang]["no_keys"] kb = [[InlineKeyboardButton(LANG[lang]["back"], callback_data='o_back')]] await q.edit_message_text(msg, reply_markup=InlineKeyboardMarkup(kb)) return # Paginate keys paginated = paginate_list(all_keys, page, KEYS_PER_PAGE) msg = "🔑 " + ("جميع المفاتيح" if lang == "ar" else "ALL KEYS" if lang == "en" else "ВСЕ КЛЮЧИ") + "\n\n" msg += LANG[lang]["page_info"].format(current=paginated['page'], total=paginated['total_pages']) + "\n" msg += f"📊 Total: {paginated['total_items']} keys\n\n" for key, rec in paginated['items']: status_emoji = "✅" if rec.get("status") == "active" else "⏳" admin_id = rec.get("admin", "Unknown") if rec.get("status") == "active": ip = rec.get("activated_ip", "N/A") exp = rec.get("expires_at", 0) if exp > time.time(): days = int((exp - time.time()) / 86400) msg += f"{status_emoji} {key}\n" msg += f" IP: {ip} | Admin: {admin_id}\n" msg += f" Expires: {days}d\n\n" else: msg += f"❌ {key} (Expired)\n\n" else: msg += f"{status_emoji} {key} (Pending)\n" msg += f" Admin: {admin_id}\n\n" # Create keyboard with pagination kb = [] for key, rec in paginated['items']: kb.append([InlineKeyboardButton( f"🔑 {key[:13]}...", callback_data=f'okey_{key}' )]) # Add pagination buttons kb.extend(create_pagination_keyboard('o_all_keys', paginated['page'], paginated['total_pages'], 'o_back', lang)) await q.edit_message_text(msg, reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.HTML) # ═══════════════════════════════════════════════════════════════ # 6. ADMIN BOT - Replace 'a_keys' handler in admin_callback: # ═══════════════════════════════════════════════════════════════ elif q.data == 'a_keys' or q.data.startswith('a_keys_page_'): # Extract page number page = 1 if q.data.startswith('a_keys_page_'): try: page = int(q.data.split('_')[-1]) except: page = 1 lkeys = load_license_keys() admin_keys = [(k, rec) for k, rec in lkeys.items() if str(rec.get("admin", "")) == aid and rec.get("status") in ("pending", "active")] if not admin_keys: msg = LANG[lang]["no_keys"] kb = [[InlineKeyboardButton(LANG[lang]["back"], callback_data='a_back')]] await q.edit_message_text(msg, reply_markup=InlineKeyboardMarkup(kb)) return # Paginate keys paginated = paginate_list(admin_keys, page, KEYS_PER_PAGE) msg = "🔑 " + ("مفاتيحي" if lang == "ar" else "MY KEYS" if lang == "en" else "МОИ КЛЮЧИ") + "\n\n" msg += LANG[lang]["page_info"].format(current=paginated['page'], total=paginated['total_pages']) + "\n" msg += f"📊 Total: {paginated['total_items']} keys\n\n" for key, rec in paginated['items']: status_emoji = "✅" if rec.get("status") == "active" else "⏳" if rec.get("status") == "active": ip = rec.get("activated_ip", "N/A") exp = rec.get("expires_at", 0) if exp > time.time(): days = int((exp - time.time()) / 86400) date_str = datetime.fromtimestamp(exp).strftime('%Y-%m-%d') msg += f"{status_emoji} {key}\n" msg += f" IP: {ip}\n" msg += f" Expires: {days}d ({date_str})\n\n" else: msg += f"❌ {key} (Expired)\n\n" else: msg += f"{status_emoji} {key} (Pending)\n\n" # Create keyboard with pagination kb = create_pagination_keyboard('a_keys', paginated['page'], paginated['total_pages'], 'a_back', lang) await q.edit_message_text(msg, reply_markup=InlineKeyboardMarkup(kb), parse_mode=ParseMode.HTML) # ═══════════════════════════════════════════════════════════════ # 7. ADMIN BOT - Update 'a_ban' handler for pagination: # ═══════════════════════════════════════════════════════════════ elif q.data == 'a_ban' or q.data.startswith('a_ban_page_'): # Extract page number page = 1 if q.data.startswith('a_ban_page_'): try: page = int(q.data.split('_')[-1]) except: page = 1 lkeys = load_license_keys() admin_keys = [k for k, rec in lkeys.items() if str(rec.get("admin", "")) == aid and rec.get("status") in ("pending", "active") and not rec.get("banned", False)] if not admin_keys: msg = LANG[lang]["no_keys"] kb = [[InlineKeyboardButton(LANG[lang]["back"], callback_data='a_back')]] await q.edit_message_text(msg, reply_markup=InlineKeyboardMarkup(kb)) return # Paginate keys paginated = paginate_list(admin_keys, page, KEYS_PER_PAGE) msg = LANG[lang]["select_key_ban"] + "\n\n" msg += LANG[lang]["page_info"].format(current=paginated['page'], total=paginated['total_pages']) kb = [] for key in paginated['items']: kb.append([InlineKeyboardButton(key, callback_data=f'ban_{key}')]) # Add pagination buttons kb.extend(create_pagination_keyboard('a_ban', paginated['page'], paginated['total_pages'], 'a_back', lang)) await q.edit_message_text(msg, reply_markup=InlineKeyboardMarkup(kb)) # ═══════════════════════════════════════════════════════════════ # 8. Handle page_info callback (does nothing, just for display): # ═══════════════════════════════════════════════════════════════ elif q.data == 'page_info': await q.answer(LANG[lang].get("page_info", "Page info"), show_alert=False) # ═══════════════════════════════════════════════════════════════ # End of patch # ═══════════════════════════════════════════════════════════════ # NOTES: # - KEYS_PER_PAGE = 8 means 8 keys per page (you can change this) # - Pagination works for: # * Owner: All Keys view # * Admin: My Keys view # * Admin: Ban Key selection # - Navigation buttons appear only when needed # - Page info shows current page / total pages # - Keys are displayed with full details (IP, expiry, status)