def data_keyboard( data: Union[List[Project], List[Campus]], action: str, content: Union[str, int], limit: int, current_id: int = 0, page: int = 0, back_button_data: Tuple[str, str] = None) -> InlineKeyboardMarkup: keyboard = InlineKeyboardMarkup(row_width=3) count = len(data[page * limit:]) data = paginate(data=data, page=page, limit=limit) for entity in data: text = entity.name if current_id != entity.id else f'✅ {entity.name}' callback_data = f'{action}.{content}.{entity.id}.{page}' keyboard.insert(InlineKeyboardButton(text, callback_data=callback_data)) keyboard = pagination_keyboard(action=f'{action}_pagination', count=count, content=content, limit=limit, stop=9, page=page, keyboard=keyboard, back_button_data=back_button_data) return keyboard
async def friends_pagination(callback_query: CallbackQuery, user_data: Tuple[Campus, Peer, User]): await dp.current_state(user=callback_query.from_user.id ).set_state(States.THROTTLER) *_, user = user_data page = int(callback_query.data.split('.')[-1]) with suppress(MessageNotModified, MessageToEditNotFound): await callback_query.message.edit_text( Config.local.wait.get(user.language)) texts = [''] friends = await UserPeer.get_friends(user_id=user.id) count = len(friends[page * 10:]) while not count and page: page -= 1 count = len(friends[page * 10:]) friends = paginate(friends, page=page, limit=10) friends_count = await UserPeer.get_friends_count(user_id=user.id) observables = await UserPeer.get_observables(user_id=user.id) for i, friend in enumerate(friends, page * 10 + 1): await callback_query.message.bot.send_chat_action(user.id, 'typing') texts[0] = Config.local.friends_list.get(user.language, from_=page * 10 + 1, to=i, friends_count=friends_count) peer, text = await text_compile.peer_data_compile(user=user, login=friend.login, is_single=False) texts.append(text) if not i % 3: try: with suppress(MessageNotModified, MessageToEditNotFound): await callback_query.message.edit_text( '\n\n'.join(texts), disable_web_page_preview=True) except RetryAfter as e: await callback_query.message.answer(str(e)) await asyncio.sleep(e.timeout) text = '\n\n'.join(texts) await Cache().set(key=f'Friends:{user.id}:{page + 1}', value=texts) keyboard = peer_keyboard( peers=friends, friends=friends, observables=observables, payload='' if friends_count < 11 else 'pagination') keyboard = pagination_keyboard(action='friends_pagination', count=count, content=page + 1, limit=10, stop=3, page=page, keyboard=keyboard) with suppress(MessageToDeleteNotFound, MessageCantBeDeleted): await callback_query.message.delete() await dp.current_state(user=user.id).set_state(States.GRANTED) await bot.send_message( user.id, text, reply_markup=keyboard, disable_web_page_preview=not (friends_count == 1 and user.show_avatar))
async def friends_list(callback_query: CallbackQuery, user_data: Tuple[Campus, Peer, User]): await dp.current_state(user=callback_query.from_user.id ).set_state(States.THROTTLER) *_, user = user_data peer_id, login = callback_query.data.split('.')[1:-1] alert_text = Config.local.remove_friend.get(user.language, login=login) await callback_query.answer(alert_text, show_alert=True) await UserPeer.remove_friend(user_id=user.id, peer_id=int(peer_id)) friends_count = await UserPeer.get_friends_count(user_id=user.id) friends = await UserPeer.get_friends(user_id=user.id) observables = await UserPeer.get_observables(user_id=user.id) current_page = 1 raws = [ button.callback_data for row in callback_query.message.reply_markup.inline_keyboard for button in row ][-1].split('.') if friends_count + 1 > 10 and raws[0] == 'friends_pagination': current_page = int(raws[1]) await callback_query.message.bot.send_chat_action(user.id, 'typing') text, page = await text_compile.friends_list_normalization( user=user, current_page=current_page, removable=login, friends=friends, friends_count=friends_count) count = len(friends[(page - 1) * 10:]) friends = paginate(friends, page=page - 1, limit=10) payload = '' if friends_count > 11: payload = 'pagination' if friends_count == 1: payload = 'alone_peer' keyboard = peer_keyboard(peers=friends, friends=friends, observables=observables, payload=payload) if friends_count + 1 > 10: keyboard = pagination_keyboard(action='friends_pagination', count=count, content=current_page, limit=10, stop=3, page=page - 1, keyboard=keyboard) if friends_count == 1: keyboard = alone_peer_keyboard(user=user, login=friends[0].login, keyboard=keyboard) with suppress(MessageToDeleteNotFound, MessageCantBeDeleted): await callback_query.message.delete() await dp.current_state(user=user.id).set_state(States.GRANTED) await bot.send_message( user.id, text, reply_markup=keyboard, disable_web_page_preview=not (friends_count == 1 and user.show_avatar))
async def peer_feedbacks_compile(self, user: User, login: str, page: int = 0, message_text: str = None ) -> Tuple[str, int, bool]: is_wrong = self._is_wrong_name(name=login) if is_wrong: return Config.local.not_found.get(user.language, login=is_wrong.replace( "<", "<")), 0, False user.show_avatar = False try: feedbacks = await Feedback().get_peer_feedbacks(login=login) if not page: peer = await Peer().get_peer(login=login, extended=False) title = self._get_peer_title(status=peer.status, url=peer.link, full_name=peer.full_name, login=peer.login) else: title = self._get_title_from_message(message_text=message_text) except (UnknownIntraError, TimeoutIntraError) as e: return f'{hbold(login, ":", sep="")} {e}', 0, False except NotFoundIntraError: return Config.local.not_found.get(user.language, login=login.replace( "<", "<")), 0, False if not feedbacks: return Config.local.not_eval.get(user.language, title=title), 0, True count = len(feedbacks[page * 5:]) feedbacks = paginate(data=feedbacks, page=page, limit=5) texts = [] for feedback in feedbacks: final_mark = feedback.final_mark if final_mark is None: final_mark = Config.local.not_closed.get(user.language) text = f'{hbold(feedback.team)} [{feedback.project}]\n' \ f'{hbold(login, ":", sep="")} {hitalic(feedback.corrector_comment)}\n' \ f'{hbold(Config.local.mark.get(user.language), ":", sep="")} {feedback.mark}\n' \ f'{feedback.peer}: {hitalic(feedback.peer_comment)}\n' \ f'{hbold(Config.local.rating.get(user.language), ":", sep="")} {feedback.rating}/5\n' \ f'{hbold(Config.local.final_mark.get(user.language), ":", sep="")} {final_mark}' texts.append(text) return title + f'\n{"—" * 20}\n'.join(texts), count, True
async def peer_locations_compile(self, user: User, login: str, page: int = 0, message_text: str = None ) -> Tuple[str, int, bool]: is_wrong = self._is_wrong_name(name=login) if is_wrong: return Config.local.not_found.get(user.language, login=is_wrong.replace( "<", "<")), 0, False try: locations = await Host().get_peer_locations(login=login) if not page: peer = await Peer().get_peer(login=login, extended=False) title = self._get_peer_title(status=peer.status, url=peer.link, full_name=peer.full_name, login=peer.login) else: title = self._get_title_from_message(message_text=message_text) except (UnknownIntraError, TimeoutIntraError) as e: return f'{hbold(login, ":", sep="")} {e}', 0, False except NotFoundIntraError: return Config.local.not_found.get(user.language, login=login.replace( "<", "<")), 0, False if not locations: return Config.local.not_logged.get(user.language, title=title), 0, True count = len(locations[page * 10:]) locations = paginate(data=locations, page=page, limit=10) texts = [] for location in locations: campus = await self._get_campus(campus_id=location.campus_id) log_time = self._get_log_time(begin_at_iso=location.begin_at, end_at_iso=location.end_at, time_zone=campus.time_zone, now=Config.local.now.get( user.language)) text = f'{hbold(campus.name)} {hcode(location.host)}\n{log_time}' texts.append(text) return title + '\n'.join(texts), count, True
async def free_locations_compile(self, user: User, campus_id: int, page: int = 0) -> Tuple[str, int, int]: campus = await self._get_campus(campus_id=campus_id) try: scan, active, inactive = await Config.intra.get_campus_locations( campus_id=campus_id, time_zone=campus.time_zone) except (UnknownIntraError, NotFoundIntraError, TimeoutIntraError) as e: return f'{hbold(campus.name, ":", sep="")} {e}', 0, 0 locations = {} for location in inactive: if location['host'] not in locations: locations.update({location['host']: location}) for location in active: locations.pop(location['host'], '') locations = list(locations.items())[:400] locations.sort() active = len(active) now = self._get_str_time( datetime.fromtimestamp(scan).isoformat(), campus.time_zone) count = len(locations[page * 40:]) while not count and page: page -= 1 count = len(locations[page * 40:]) locations = paginate(data=locations, page=page, limit=40) texts = [] for data in locations: location = Host.from_dict(data=data[1]) end_at = self._get_str_time(iso_format=location.end_at, time_zone=campus.time_zone) text = f'{hcode(location.host)} | {hcode(location.login)} | {end_at}' texts.append(text) body = Config.local.locations_disclaimer.get(user.language) if texts: body = Config.local.locations_body.get(user.language) title = Config.local.locations_title.get(user.language, campus_name=campus.name, now=now, active=active, body=body) return title + '\n'.join(texts), count, page
def paginate_text(self, page=1, delimiter=' ') -> str: paginated_text = paginate(data=self.text.split(sep=delimiter), page=int(page) - 1, limit=self.limit) return delimiter.join(paginated_text)