From 104c0b32a1e30a56900bb6a17ab9a009c54b76bb Mon Sep 17 00:00:00 2001 From: Dmitrii Morozov Date: Tue, 7 May 2024 16:16:57 +0200 Subject: Refactoring --- Commands.py | 4 +-- FortniteClient.py | 75 +++++++++++++++++++++++++++++++---------------- FortniteEvents.py | 55 ++++++++++++++++++---------------- FortniteStatusNotifier.py | 27 ++++++++--------- tgbot.py | 72 ++++++++++++++++++++------------------------- 5 files changed, 124 insertions(+), 109 deletions(-) diff --git a/Commands.py b/Commands.py index 926b25b..e49d333 100644 --- a/Commands.py +++ b/Commands.py @@ -81,12 +81,10 @@ class GetTodayStatsCommand(CommandHandler): class RecordStatsCommand(CommandHandler): - __telegramBot: TelegramBot __fortniteClient: FortniteClient __statsRepository: StatsRepository - def __init__(self, telegramBot: TelegramBot, fortniteClient: FortniteClient, statsRepository: StatsRepository): - self.__telegramBot = telegramBot + def __init__(self, fortniteClient: FortniteClient, statsRepository: StatsRepository): self.__fortniteClient = fortniteClient self.__statsRepository = statsRepository diff --git a/FortniteClient.py b/FortniteClient.py index a8e6774..1f700b2 100755 --- a/FortniteClient.py +++ b/FortniteClient.py @@ -5,21 +5,30 @@ import json import os import typing from DeviceAuth import DeviceAuth -from FortniteEvents import * from Types import * __fortnite_account_key__ = 'fornite-account-key' +# Intefaces for events +class FriendPresenceObserver: + async def update(self, display_name: str, playing: bool, party_size: int) -> None: + pass + +class ClientInitObserver: + async def on_event(self, fortniteClient) -> None: + pass + class FortniteClient(fortnitepy.Client): - device_auth = DeviceAuth() - presenceObserver = None - clientInit = None + __device_auth: DeviceAuth + __friendPresenceObserver: FriendPresenceObserver + __clientInitObserver: ClientInitObserver - def __init__(self, friendPresenceObserver: PresenceObserver, clientInit: ClientInit): - self.presenceObserver = friendPresenceObserver - self.clientInit = clientInit - if self.device_auth.device_auth_file_exists(): + def __init__(self, clientInitObserver: ClientInitObserver, friendPresenceObserver: FriendPresenceObserver): + self.__device_auth = DeviceAuth() + self.__clientInitObserver = clientInitObserver + self.__friendPresenceObserver = friendPresenceObserver + if self.__device_auth.device_auth_file_exists(): self.__auth_device_auth() else: self.__auth_authorization_code() @@ -40,19 +49,16 @@ class FortniteClient(fortnitepy.Client): ) def __auth_device_auth(self): - device_auth_details = self.device_auth.get_device_auth_details().get(__fortnite_account_key__, {}) + device_auth_details = self.__device_auth.get_device_auth_details().get(__fortnite_account_key__, {}) super().__init__( auth=fortnitepy.DeviceAuth( **device_auth_details ) ) - async def event_device_auth_generate(self, details, email): - self.device_auth.store_device_auth_details(email, details) - # Generate auth details if none were supplied yet - async def generate_auth_details(self): - if not self.device_auth.device_auth_file_exists(): + async def __generate_auth_details(self): + if not self.__device_auth.device_auth_file_exists(): device_auth_data = await self.auth.generate_device_auth() details = { 'device_id': device_auth_data['deviceId'], @@ -66,20 +72,37 @@ class FortniteClient(fortnitepy.Client): __fortnite_account_key__ ) - async def event_ready(self): - print('----------------') - print('FortniteClient ready as:') - print(self.user.display_name) - print(self.user.id) - print('----------------') + async def event_device_auth_generate(self, details, email): + self.__device_auth.store_device_auth_details(email, details) - await self.generate_auth_details() - - # Call observers - await self.clientInit.on_event() + async def event_ready(self): + await self.__generate_auth_details() + await self.__clientInitObserver.on_event(self) async def event_friend_request(self, request: typing.Union[fortnitepy.friend.IncomingPendingFriend, fortnitepy.friend.OutgoingPendingFriend]): - await IncomingFriendRequest.on_event(request) + await IncomingFriendRequestEvent.on_event(request) async def event_friend_presence(self, before, after: fortnitepy.Presence): - await FriendPresence.on_event(before, after, self.presenceObserver) \ No newline at end of file + await FriendPresenceEvent.on_event(before, after, self.__friendPresenceObserver) + +class FriendPresenceEvent: + async def on_event(before, after: fortnitepy.Presence, friendPresenceObserver: FriendPresenceObserver): + if before is not None and after is not None: + if before.playing != after.playing: + print('FriendPresence changed for user {}, before {}, after {}'.format(after.friend.display_name, before.playing, after.playing)) + party_size: int = 1 + if after.has_properties: + party: fortnitepy.PresenceParty = after.party + if party is not None and party.playercount is not None: + party_size = int(party.playercount) + await friendPresenceObserver.update( + after.friend.display_name, + after.playing, + party_size) + +class IncomingFriendRequestEvent: + async def on_event(request: typing.Union[fortnitepy.friend.IncomingPendingFriend, fortnitepy.friend.OutgoingPendingFriend]): + if isinstance(request, fortnitepy.friend.IncomingPendingFriend): + incoming_request = typing.cast(fortnitepy.friend.IncomingPendingFriend, request) + print('Accepting friend request from {}'.format(incoming_request.display_name)) + #await incoming_request.accept() \ No newline at end of file diff --git a/FortniteEvents.py b/FortniteEvents.py index 995d646..77452cc 100644 --- a/FortniteEvents.py +++ b/FortniteEvents.py @@ -1,32 +1,35 @@ import fortnitepy import typing +import time +from FortniteClient import * +from TelegramBot import * +from persistence import PresenceRepository +from Formatter import * -class IncomingFriendRequest: - async def on_event(request: typing.Union[fortnitepy.friend.IncomingPendingFriend, fortnitepy.friend.OutgoingPendingFriend]): - if isinstance(request, fortnitepy.friend.IncomingPendingFriend): - incoming_request = typing.cast(fortnitepy.friend.IncomingPendingFriend, request) - print('Accepting friend request from {}'.format(incoming_request.display_name)) - #await incoming_request.accept() +class ClientInitObserverImpl(ClientInitObserver): + async def on_event(self, fortniteClient: FortniteClient) -> None: + print('----------------') + print('FortniteClient ready as:') + print(fortniteClient.user.display_name) + print(fortniteClient.user.id) + print('----------------') -class PresenceObserver: - async def update(self, display_name: str, playing: bool, party_size: int) -> None: - pass +class FriendPresenceObserverImpl(FriendPresenceObserver): + + __telegramBot: TelegramBot + __presenceRepository: PresenceRepository -class ClientInit: - async def on_event(self) -> None: - pass + def __init__(self, telegramBot: TelegramBot, presenceRepository: PresenceRepository): + self.__telegramBot = telegramBot + self.__presenceRepository = presenceRepository + + async def update(self, display_name: str, playing: bool, party_size: int) -> None: + if playing: + last_presence = self.__presenceRepository.getLastUserPresence(display_name) + diff = time.time() - last_presence + if diff > 60 * 60: # 60 minutes + await self.__notifyFriendPlaying(display_name, party_size) + self.__presenceRepository.setLastUserPresence(display_name, time.time()) -class FriendPresence: - async def on_event(before, after: fortnitepy.Presence, observer: PresenceObserver): - if before is not None and after is not None: - if before.playing != after.playing: - print('FriendPresence changed for user {}, before {}, after {}'.format(after.friend.display_name, before.playing, after.playing)) - party_size: int = 1 - if after.has_properties: - party: fortnitepy.PresenceParty = after.party - if party is not None and party.playercount is not None: - party_size = int(party.playercount) - await observer.update( - after.friend.display_name, - after.playing, - party_size) + async def __notifyFriendPlaying(self, display_name: str, party_size: int): + await self.__telegramBot.send_message_to_all(formatFriendOnline(display_name, party_size)) \ No newline at end of file diff --git a/FortniteStatusNotifier.py b/FortniteStatusNotifier.py index 81c7d12..7932380 100644 --- a/FortniteStatusNotifier.py +++ b/FortniteStatusNotifier.py @@ -6,33 +6,32 @@ from pythonFortniteStatus.FortniteStatus import * # Polling interval in seconds __polling_interval__ = 5 * 60 # 5 minutes -fortniteStatus = FortniteStatus() - -class Observer: - async def update(self, fortniteStatus) -> None: +class FortniteStatusObserver: + async def update(self, fortnite_status) -> None: pass class FortniteStatusNotifier: - observer = None - fortniteStatus = None + __fortniteStatusObserver: FortniteStatusObserver + __fortniteStatus: FortniteStatus + __lastFortniteStatus: any - def __init__(self, observer: Observer): - self.observer = observer + def __init__(self, fortniteStatusObserver: FortniteStatusObserver): + self.__fortniteStatusObserver = fortniteStatusObserver + self.__fortniteStatus = FortniteStatus() async def run(self): # Initialize status - self.fortniteStatus = fortniteStatus.getStatus() + self.__lastFortniteStatus = self.__fortniteStatus.getStatus() while True: await self.__readStatus() await asyncio.sleep(__polling_interval__) async def __readStatus(self): - serviceStatusTmp = fortniteStatus.getStatus() - if serviceStatusTmp != self.fortniteStatus: + serviceStatusTmp = self.__fortniteStatus.getStatus() + if serviceStatusTmp != self.__lastFortniteStatus: await self.__notify(serviceStatusTmp) - self.fortniteStatus = serviceStatusTmp + self.__lastFortniteStatus = serviceStatusTmp async def __notify(self, fortniteStatus): - print("Fortnite status changed, notifying observers") - await self.observer.update(fortniteStatus) \ No newline at end of file + await self.__fortniteStatusObserver.update(fortniteStatus) \ No newline at end of file diff --git a/tgbot.py b/tgbot.py index 1bab35e..360f3b0 100755 --- a/tgbot.py +++ b/tgbot.py @@ -9,55 +9,43 @@ from persistence import UserRepository, StatsRepository, PresenceRepository from TelegramBot import TelegramBot, CommandHandler from Commands import * -class ClientInitObserver(ClientInit): - async def on_event(self) -> None: - # Accept pending friends - for friend_request in fortniteClient.incoming_pending_friends: - await fortniteClient.event_friend_request(friend_request) +class FortniteStatusObserverImpl(FortniteStatusObserver): - # Record user stats - if len(statsRepository.getStats()) == 0: - await recordStatsCommand.handle(None) + telegram_bot: TelegramBot + + def __init__(self, telegram_bot: TelegramBot): + self.__telegram_bot = telegram_bot -class FortniteStatusObserver(Observer): - async def update(self, fortniteStatus) -> None: - await telegramBot.send_message_to_all(formatFortniteStatus(fortniteStatus)) + async def update(self, fortnite_status) -> None: + await self.__telegram_bot.send_message_to_all(formatFortniteStatus(fortnite_status)) -class FortnitePresenceObserver(PresenceObserver): - async def update(self, display_name: str, playing: bool, party_size: int) -> None: - if playing: - last_presence = prensenceRepository.getLastUserPresence(display_name) - diff = time.time() - last_presence - if diff > 60 * 60: # 60 minutes - await self.__notifyFriendPlaying(display_name, party_size) - prensenceRepository.setLastUserPresence(display_name, time.time()) +user_repository = UserRepository() +stats_repository = StatsRepository() +presence_repository = PresenceRepository() +telegram_bot = TelegramBot(user_repository) +fortnite_status_notifier = FortniteStatusNotifier(FortniteStatusObserverImpl(telegram_bot)) - async def __notifyFriendPlaying(self, display_name: str, party_size: int): - await telegramBot.send_message_to_all(formatFriendOnline(display_name, party_size)) +fortnite_client = FortniteClient( + ClientInitObserverImpl(), + FriendPresenceObserverImpl(telegram_bot, presence_repository)) -userRepository = UserRepository() -statsRepository = StatsRepository() -prensenceRepository = PresenceRepository() -telegramBot = TelegramBot(userRepository) -fortniteStatusWrapper = FortniteStatusNotifier(FortniteStatusObserver()) -fortniteClient = FortniteClient(FortnitePresenceObserver(), ClientInitObserver()) -recordStatsCommand = RecordStatsCommand(telegramBot, fortniteClient, statsRepository) +record_stats_command = RecordStatsCommand(fortnite_client, stats_repository) -telegramBot.register_command_handler('start', StartCommand(telegramBot, userRepository)) -telegramBot.register_command_handler('status', GetStatusCommand(telegramBot)) -telegramBot.register_command_handler('friends', GetFriendsCommand(telegramBot, fortniteClient)) -telegramBot.register_command_handler('stats', GetStatsCommand(telegramBot, fortniteClient)) -telegramBot.register_command_handler('todaystats', GetTodayStatsCommand(telegramBot, fortniteClient, statsRepository)) -telegramBot.register_command_handler('recordstats', recordStatsCommand) +telegram_bot.register_command_handler('start', StartCommand(telegram_bot, user_repository)) +telegram_bot.register_command_handler('status', GetStatusCommand(telegram_bot)) +telegram_bot.register_command_handler('friends', GetFriendsCommand(telegram_bot, fortnite_client)) +telegram_bot.register_command_handler('stats', GetStatsCommand(telegram_bot, fortnite_client)) +telegram_bot.register_command_handler('todaystats', GetTodayStatsCommand(telegram_bot, fortnite_client, stats_repository)) +telegram_bot.register_command_handler('recordstats', record_stats_command) async def run_tgbot(): - await telegramBot.run() + await telegram_bot.run() -async def run_fortniteStatusWrapper(): - await fortniteStatusWrapper.run() +async def run_fortnite_status_notifier(): + await fortnite_status_notifier.run() -async def run_fortniteClient(): - fortniteClient.run() +async def run_fortnite_client(): + fortnite_client.run() async def run_record_stats(): while True: @@ -67,7 +55,11 @@ async def run_record_stats(): await asyncio.sleep(60 * 60) # 1 hour async def run_all(): - await asyncio.gather(run_tgbot(), run_fortniteStatusWrapper(), run_fortniteClient(), run_record_stats()) + await asyncio.gather( + run_tgbot(), + run_fortnite_status_notifier(), + run_fortnite_client(), + run_record_stats()) if __name__ == '__main__': nest_asyncio.apply() -- cgit v1.2.3