summaryrefslogtreecommitdiff
path: root/fortnite_status
diff options
context:
space:
mode:
authorDmitrii Morozov <snoopdesigns@gmail.com>2024-05-07 17:15:25 +0200
committerDmitrii Morozov <snoopdesigns@gmail.com>2024-05-07 17:15:25 +0200
commitee3e87a6ec19878d56e8f386b20c58e4d9b211b3 (patch)
treec111165b0310581abeea0cecbfd9dabe2933e0d9 /fortnite_status
parentcfa79cbbaf42a8f74a2cd4bca4d1d495b4d597f1 (diff)
Modules
Diffstat (limited to 'fortnite_status')
-rw-r--r--fortnite_status/__init__.py119
1 files changed, 119 insertions, 0 deletions
diff --git a/fortnite_status/__init__.py b/fortnite_status/__init__.py
new file mode 100644
index 0000000..244502b
--- /dev/null
+++ b/fortnite_status/__init__.py
@@ -0,0 +1,119 @@
+# Simple utility class which provides an access to Fortnite service status report.
+# Usage: ForniteStatus().getStatus()
+
+import requests as req
+import html5lib
+from bs4 import BeautifulSoup
+
+# Polling interval in seconds
+__polling_interval__ = 5 * 60 # 5 minutes
+
+class FortniteStatusObserver:
+ async def update(self, fortnite_status) -> None:
+ pass
+
+class FortniteStatus:
+ """
+ Instantiate a FortniteStatus class.
+ """
+
+ class Status:
+ serviceStatuses = []
+
+ def __init__(self, serviceStatuses):
+ self.serviceStatuses = serviceStatuses
+
+ def __eq__(self, other):
+ if not isinstance(other, FortniteStatus.Status):
+ return NotImplemented
+ return sorted(self.serviceStatuses) == sorted(other.serviceStatuses)
+
+ def prettify(self):
+ return 'Fortnite services status:\n' + '\n'.join([serviceStatus.prettify() for serviceStatus in self.serviceStatuses])
+
+ class ServiceStatus:
+ serviceName = ''
+ status = False
+
+ def __init__(self, serviceName, status):
+ self.serviceName = serviceName
+ self.status = status
+
+ def __lt__(self, other):
+ if not isinstance(other, FortniteStatus.ServiceStatus):
+ return NotImplemented
+ return self.serviceName < other.serviceName
+
+ def __eq__(self, other):
+ if not isinstance(other, FortniteStatus.ServiceStatus):
+ return NotImplemented
+ return self.serviceName == other.serviceName and self.status == other.status
+
+
+ def prettify(self):
+ return f'{self.serviceName}, {self.status}'
+
+ def __findFortniteStatusHtmlComponent(self, html):
+ for component in html.findAll('div', {'class': 'component-container'}):
+ innerContainers = component.findAll('div', {'class': 'component-inner-container'})
+ for innerContainer in innerContainers:
+ for names in innerContainer.findAll('span', {'class': 'name'}):
+ for name in names.findAll('span'):
+ if 'class' not in name.attrs and 'Fortnite' in name.text:
+ return component
+
+ def __parseFortniteStatus(self, html):
+ component = self.__findFortniteStatusHtmlComponent(html)
+ serviceStatuses = []
+ childContainer = component.find('div', {'class': 'child-components-container'})
+ for innerContainer in childContainer.findAll('div', {'class': 'component-inner-container'}):
+ name = innerContainer.find('span', {'class': 'name'}).text.strip()
+ statusString = innerContainer.find('span', {'class': 'component-status'}).text.strip()
+ if statusString == 'Operational':
+ statusCode = True
+ else:
+ statusCode = False
+ serviceStatuses.append(self.ServiceStatus(name, statusCode))
+ return self.Status(serviceStatuses)
+
+ def getStatus(self):
+ webContent = req.get("https://status.epicgames.com/")
+ parsedHtml = BeautifulSoup(webContent.text, 'html5lib')
+
+ return self.__parseFortniteStatus(parsedHtml)
+
+
+
+ def printStatus(self):
+ """
+ Prints a current Fortnite services status in stdout.
+ Example:
+
+ """
+ print(self.getStatus().prettify())
+
+class FortniteStatusNotifier:
+
+ __fortnite_status_observer: FortniteStatusObserver
+ __fortnite_status: FortniteStatus
+ __last_fortnite_status: any
+
+ def __init__(self, fortnite_status_observer: FortniteStatusObserver):
+ self.__fortnite_status_observer = fortnite_status_observer
+ self.__fortnite_status = FortniteStatus()
+
+ async def run(self):
+ # Initialize status
+ self.__last_fortnite_status = self.__fortnite_status.getStatus()
+ while True:
+ await self.__read_status()
+ await asyncio.sleep(__polling_interval__)
+
+ async def __read_status(self):
+ service_status_tmp = self.__fortnite_status.getStatus()
+ if service_status_tmp != self.__last_fortnite_status:
+ await self.__notify(service_status_tmp)
+ self.__last_fortnite_status = service_status_tmp
+
+ async def __notify(self, fortnite_status):
+ await self.__fortnite_status_observer.update(fortnite_status) \ No newline at end of file