import fortnitepy import typing import time import datetime from fortnite_client import * from telegram_bot import * from persistence import * from formatter import * __accept_keyword__ = "accept" __decline_keyword__ = "decline" class ClientInitObserverImpl(ClientInitObserver): async def on_event(self, fortnite_client: FortniteClient) -> None: print('----------------') print('FortniteClient ready as:') print(fortnite_client.user.display_name) print(fortnite_client.user.id) print('----------------') class FriendPresenceObserverImpl(FriendPresenceObserver): __telegram_bot: TelegramBot __presence_repository: PresenceRepository def __init__(self, telegram_bot: TelegramBot, presence_repository: PresenceRepository): self.__telegram_bot = telegram_bot self.__presence_repository = presence_repository async def update(self, display_name: str, playing: bool, party_size: int) -> None: if playing: last_presence = self.__presence_repository.get_last_user_presence(display_name) diff = time.time() - last_presence if diff > 60 * 60: # 60 minutes await self.__notify_friend_playing(display_name, party_size) self.__presence_repository.set_last_user_presence(display_name, time.time()) async def __notify_friend_playing(self, display_name: str, party_size: int): await self.__telegram_bot.send_message_to_all(format_friend_online(display_name, party_size)) class NewFriendObserverImpl(NewFriendObserver): __telegram_bot: TelegramBot __stats_repository: StatsRepository def __init__(self, telegram_bot: TelegramBot, stats_repository: StatsRepository): self.__telegram_bot = telegram_bot self.__stats_repository = stats_repository async def on_new_friend_request(self, request_id: str, display_name: str, fortnite_client: FortniteClient) -> None: __new_friend_reply_markup = telebot.types.InlineKeyboardMarkup() __new_friend_reply_markup.add(telebot.types.InlineKeyboardButton('Accept', callback_data="{}:{}:{}".format(__accept_keyword__, request_id, display_name))) __new_friend_reply_markup.add(telebot.types.InlineKeyboardButton('Decline', callback_data="{}:{}:{}".format(__decline_keyword__, request_id, display_name))) self.__telegram_bot.register_callback_query( NewFriendCallbackQueryHandler(self.__telegram_bot, fortnite_client, self), lambda call: call.data.startswith(__accept_keyword__) or call.data.startswith(__decline_keyword__)) await self.__telegram_bot.send_message_to_all(format_new_friend_request(display_name), reply_markup=__new_friend_reply_markup) async def on_friend_added(self, fornite_friend: fortnitepy.friend.Friend) -> None: # Try fetch stats try: await self.__try_get_stats(fornite_friend) except: print(traceback.format_exc()) await self.__on_unavailable_public_stats(fornite_friend.display_name) friend = User.from_fortnite_friend(fornite_friend) await self.__stats_repository.put_stats(friend, datetime.datetime.now()) await self.__telegram_bot.send_message_to_all(format_new_friend(friend.display_name)) async def __try_get_stats(self, friend: fortnitepy.friend.Friend): await friend.fetch_br_stats() async def __on_unavailable_public_stats(self, display_name) -> None: await self.__telegram_bot.send_message_to_all(format_friend_disabled_public_stats(display_name)) class NewFriendCallbackQueryHandler(CallbackQueryHandler): __telegram_bot: TelegramBot __fortnite_client: FortniteClient __new_friend_observer: NewFriendObserver def __init__(self, telegram_bot: TelegramBot, fortnite_client: FortniteClient, new_friend_observer: NewFriendObserver): self.__telegram_bot = telegram_bot self.__fortnite_client = fortnite_client self.__new_friend_observer = new_friend_observer async def handle(self, call: telebot.types.CallbackQuery): if self.__fortnite_client.is_initialized(): answered: bool = False if call.data.startswith(__accept_keyword__) or call.data.startswith(__decline_keyword__): splitted = call.data.split(":") await self.__handle_request(splitted[0], splitted[1], splitted[2]) await self.__telegram_bot.answer_callback_query(callback_query_id=call.id) async def __handle_request(self, action: str, request_id: str, display_name: str): pending_friends = self.__fortnite_client.pending_friends for pending_friend in pending_friends: if isinstance(pending_friend, fortnitepy.friend.IncomingPendingFriend): incoming_request = typing.cast(fortnitepy.friend.IncomingPendingFriend, pending_friend) if incoming_request._id == request_id: if action == __accept_keyword__: await incoming_request.accept() accepted_friend = incoming_request.client.get_friend(incoming_request._id) await self.__new_friend_observer.on_friend_added(accepted_friend) elif action == __decline_keyword__: await incoming_request.decline() await self.__telegram_bot.send_message_to_all(format_friend_declined(display_name))