summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitrii Morozov <snoopdesigns@gmail.com>2025-01-05 22:33:28 +0100
committerDmitrii Morozov <snoopdesigns@gmail.com>2025-01-05 22:33:28 +0100
commit694eadd7f06f65b925d2c06a3492bd7d9153d016 (patch)
tree2c9d993c5882218c980b3af6e091b2d5dbf9c597
parent71c11730713f7d5ebe07175d5701cbe8434bb5da (diff)
Add query to accept or decline new friends
-rw-r--r--formatter/__init__.py19
-rw-r--r--fortnite_client/__init__.py38
-rw-r--r--fortnite_client/fortnite_events.py64
-rw-r--r--telegram_bot/__init__.py3
-rw-r--r--telegram_bot/commands.py5
5 files changed, 97 insertions, 32 deletions
diff --git a/formatter/__init__.py b/formatter/__init__.py
index 0642a40..460312a 100644
--- a/formatter/__init__.py
+++ b/formatter/__init__.py
@@ -149,8 +149,23 @@ def format_new_friend(display_name: str):
def format_friend_disabled_public_stats(display_name: str):
return formatting.format_text(
- 'New friend ',
+ 'New friend',
formatting.mbold('{}'.format(display_name)),
'has disabled public statistics in Fortnite profile, no statistics will be visible',
- separator=''
+ separator=' '
+ )
+
+def format_new_friend_request(display_name: str):
+ return formatting.format_text(
+ 'New friend request from',
+ formatting.mbold('{}'.format(display_name)),
+ separator=' '
+ )
+
+def format_friend_declined(display_name: str):
+ return formatting.format_text(
+ 'Friend request from',
+ formatting.mbold('{}'.format(display_name)),
+ 'declined',
+ separator=' '
) \ No newline at end of file
diff --git a/fortnite_client/__init__.py b/fortnite_client/__init__.py
index d44fee4..113f3d6 100644
--- a/fortnite_client/__init__.py
+++ b/fortnite_client/__init__.py
@@ -22,9 +22,10 @@ class ClientInitObserver:
pass
class NewFriendObserver:
- async def on_event(self, friend: User) -> None:
+ async def on_new_friend_request(self, request_id: str, display_name: str, fortnite_client: any) -> None:
+ pass
+ async def on_friend_added(self, friend: User) -> None:
pass
-
async def on_unavailable_public_stats(self, display_name) -> None:
pass
@@ -121,28 +122,17 @@ class FriendPresenceEvent:
class IncomingFriendRequestEvent:
async def on_event(request: typing.Union[fortnitepy.friend.IncomingPendingFriend, fortnitepy.friend.OutgoingPendingFriend], new_friend_observer: NewFriendObserver):
- print('Do nothing on incoming friend request..')
- #if isinstance(request, fortnitepy.friend.IncomingPendingFriend):
- #incoming_request = typing.cast(fortnitepy.friend.IncomingPendingFriend, request)
- #await incoming_request.accept()
- #accepted_friend = incoming_request.client.get_friend(request._id)
-
- #if isinstance(request, fortnitepy.friend.OutgoingPendingFriend):
- #outgoing_request = typing.cast(fortnitepy.friend.OutgoingPendingFriend, request)
- #accepted_friend = outgoing_request.client.get_friend(request._id)
+ if isinstance(request, fortnitepy.friend.IncomingPendingFriend):
+ incoming_request = typing.cast(fortnitepy.friend.IncomingPendingFriend, request)
+ await IncomingFriendRequestEvent.__handle_friend_request(incoming_request, new_friend_observer)
- #await IncomingFriendRequestEvent.__handle_new_friend(accepted_friend, new_friend_observer)
+ if isinstance(request, fortnitepy.friend.OutgoingPendingFriend):
+ outgoing_request = typing.cast(fortnitepy.friend.OutgoingPendingFriend, request)
+ accepted_friend = outgoing_request.client.get_friend(request._id)
+ await IncomingFriendRequestEvent.__handle_new_friend(accepted_friend, new_friend_observer)
- async def __handle_new_friend(accepted_friend: fortnitepy.friend.Friend, new_friend_observer: NewFriendObserver):
- # Try fetch stats
- try:
- await IncomingFriendRequestEvent.__try_get_stats(accepted_friend)
- except:
- print(traceback.format_exc())
- await new_friend_observer.on_unavailable_public_stats(accepted_friend.display_name)
-
- # Register new fried, fetch stats
- await new_friend_observer.on_event(User.from_fortnite_friend(accepted_friend))
+ async def __handle_friend_request(request: fortnitepy.friend.IncomingPendingFriend, new_friend_observer: NewFriendObserver):
+ await new_friend_observer.on_new_friend_request(request._id, request.display_name, request.client)
- async def __try_get_stats(friend: fortnitepy.Friend):
- await friend.fetch_br_stats() \ No newline at end of file
+ async def __handle_new_friend(accepted_friend: fortnitepy.friend.Friend, new_friend_observer: NewFriendObserver):
+ await new_friend_observer.on_friend_added(accepted_friend) \ No newline at end of file
diff --git a/fortnite_client/fortnite_events.py b/fortnite_client/fortnite_events.py
index 918b1e1..1efbc4e 100644
--- a/fortnite_client/fortnite_events.py
+++ b/fortnite_client/fortnite_events.py
@@ -7,6 +7,9 @@ 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('----------------')
@@ -43,10 +46,65 @@ class NewFriendObserverImpl(NewFriendObserver):
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_event(self, friend: User) -> None:
+ 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 on_unavailable_public_stats(self, display_name) -> None:
- await self.__telegram_bot.send_message_to_all(format_friend_disabled_public_stats(display_name)) \ No newline at end of file
+ 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)) \ No newline at end of file
diff --git a/telegram_bot/__init__.py b/telegram_bot/__init__.py
index c25af95..a50c71b 100644
--- a/telegram_bot/__init__.py
+++ b/telegram_bot/__init__.py
@@ -47,12 +47,13 @@ class TelegramBot:
async def answer_callback_query(self, callback_query_id):
await self.__bot.answer_callback_query(callback_query_id=callback_query_id)
- async def send_message_to_all(self, message_text: str):
+ async def send_message_to_all(self, message_text: str, reply_markup = None):
for user in self.__user_repository.get_all_users():
try:
await self.__bot.send_message(
user[0],
message_text,
+ reply_markup=reply_markup,
parse_mode='MarkdownV2'
)
except Exception as error:
diff --git a/telegram_bot/commands.py b/telegram_bot/commands.py
index 697d1e3..9c12d97 100644
--- a/telegram_bot/commands.py
+++ b/telegram_bot/commands.py
@@ -80,7 +80,8 @@ class GetStatsCallbackQueryHandler(CallbackQueryHandler):
await self.reply_with_stats_days_difference(call.message, __duration_week__)
elif call.data == __stats_month__:
await self.reply_with_stats_days_difference(call.message, __duration_month__)
- await self.__telegram_bot.answer_callback_query(callback_query_id=call.id)
+
+ await self.__telegram_bot.answer_callback_query(callback_query_id=call.id)
async def reply_with_today_stats(self, message):
friends = await self.__fortnite_client.get_friends()
@@ -117,7 +118,7 @@ class GetStatsCommand(CommandHandler):
self.__telegram_bot.register_callback_query(
GetStatsCallbackQueryHandler(self.__telegram_bot, self.__fortnite_client, self.__stats_repository),
- lambda call: True)
+ lambda call: call.data == __stats_now__ or call.data == __stats_day__ or call.data == __stats_week__ or call.data == __stats_month__)
async def handle(self, message: telebot.types.Message):
await self.__telegram_bot.reply(message, 'Which statistics would you like to see?', reply_markup=self.__reply_markup)