import requests
import atexit

from apscheduler.schedulers.background import BackgroundScheduler
from bs4 import BeautifulSoup

class lodeStoneScraper:
    def __init__(self):
        self.__URL = 'https://na.finalfantasyxiv.com/lodestone/worldstatus/'
        self.__statistics = {}
        self.update_page()

        # Setup scheduler
        self.__scheduler = BackgroundScheduler()
        self.__scheduler.add_job(func=self.update_page, trigger='interval', seconds=15)
        self.__scheduler.start()

        # Setup atexit
        atexit.register(lambda: self.__scheduler.shutdown())

    # Called to update the stored information on the servers
    def update_page(self):
        # Save old data
        temp = self.__statistics

        try:
            # Get the page content and parse it
            page = requests.get(self.__URL)
            page = BeautifulSoup(page.content, 'html.parser')

            # Extract the relevant divs
            server_names = page.find_all('div', class_='world-list__world_name')
            server_types = page.find_all('div', class_='world-list__world_category')
            server_char_status = page.find_all('div', class_='world-list__create_character')
            server_online_status = page.find_all('div', class_='world-list__status_icon')

            # Parse into text
            server_names = self.__parse_name(server_names)
            server_types = self.__parse_type(server_types)
            server_char_status = self.__parse_char_status(server_char_status)
            server_online_status = self.__parse_server_online_status(server_online_status)

            # Collate the data
            for x in range(0, len(server_names)):
                self.__statistics[server_names[x]] = [server_types[x], server_char_status[x], server_online_status[x]]
        except Exception as e:
            # If update failed, restore old data
            self.__statistics = temp

            # Log error
            print(f'An exception occurred while trying to update data: {e}')

    # Returns the currently stored data dictionary
    def get_data(self):
        return self.__statistics

    # Parses server names from raw html
    def __parse_name(self, server_names):
        names = []
        for server in server_names:
            names.append(server.find('p').getText())
        return names

    # Parses server types from the raw html (Standard or Preferred)
    def __parse_type(self, server_types):
        types = []
        for item in server_types:
            temp = item.find('p').getText()

            # If the server is offline this will return '--', set to an empty string
            if temp == '--':
                types.append('')
            else:
                types.append(temp)

        return types

    # Parses character creation status from the raw html (True = CC Available, False = CC Unavailable)
    def __parse_char_status(self, server_char_status):
        char_states = []
        for item in server_char_status:
            try:
                state = item.i['data-tooltip']
                if 'Available' in state:
                    char_states.append(True)
                else:
                    char_states.append(False)

            # An exception occurs when the server is offline, catch this and append false (no creation on an offline world)
            except Exception:
                char_states.append(False)

        return char_states

    # Parses whether a server is online from the raw html (True = Online, False = Server offline)
    def __parse_server_online_status(self, server_online_status):
        online_states = []
        for item in server_online_status:
           state = item.i['data-tooltip']
           if 'Online' in state:
               online_states.append(True)
           else:
               online_states.append(False)
        return online_states
import requests
import atexit

from apscheduler.schedulers.background import BackgroundScheduler
from bs4 import BeautifulSoup

class lodeStoneScraper:
    def __init__(self):
        self.__URL = 'https://na.finalfantasyxiv.com/lodestone/worldstatus/'
        self.__statistics = {}
        self.update_page()

        # Setup scheduler
        self.__scheduler = BackgroundScheduler()
        self.__scheduler.add_job(func=self.update_page, trigger='interval', seconds=15)
        self.__scheduler.start()

        # Setup atexit
        atexit.register(lambda: self.__scheduler.shutdown())

    # Called to update the stored information on the servers
    def update_page(self):
        # Save old data
        temp = self.__statistics

        try:
            # Get the page content and parse it
            page = requests.get(self.__URL)
            page = BeautifulSoup(page.content, 'html.parser')

            # Extract the relevant divs
            server_names = page.find_all('div', class_='world-list__world_name')
            server_types = page.find_all('div', class_='world-list__world_category')
            server_char_status = page.find_all('div', class_='world-list__create_character')
            server_online_status = page.find_all('div', class_='world-list__status_icon')

            # Parse into text
            server_names = self.__parse_name(server_names)
            server_types = self.__parse_type(server_types)
            server_char_status = self.__parse_char_status(server_char_status)
            server_online_status = self.__parse_server_online_status(server_online_status)

            # Collate the data
            for x in range(0, len(server_names)):
                self.__statistics[server_names[x]] = [server_types[x], server_char_status[x], server_online_status[x]]
        except Exception as e:
            # If update failed, restore old data
            self.__statistics = temp

            # Log error
            print(f'An exception occurred while trying to update data: {e}')

    # Returns the currently stored data dictionary
    def get_data(self):
        return self.__statistics

    # Parses server names from raw html
    def __parse_name(self, server_names):
        names = []
        for server in server_names:
            names.append(server.find('p').getText())
        return names

    # Parses server types from the raw html (Standard or Preferred)
    def __parse_type(self, server_types):
        types = []
        for item in server_types:
            temp = item.find('p').getText()

            # If the server is offline this will return '--', set to an empty string
            if temp == '--':
                types.append('')
            else:
                types.append(temp)

        return types

    # Parses character creation status from the raw html (True = CC Available, False = CC Unavailable)
    def __parse_char_status(self, server_char_status):
        char_states = []
        for item in server_char_status:
            try:
                state = item.i['data-tooltip']
                if 'Available' in state:
                    char_states.append(True)
                else:
                    char_states.append(False)

            # An exception occurs when the server is offline, catch this and append false (no creation on an offline world)
            except Exception:
                char_states.append(False)

        return char_states

    # Parses whether a server is online from the raw html (True = Online, False = Server offline)
    def __parse_server_online_status(self, server_online_status):
        online_states = []
        for item in server_online_status:
           state = item.i['data-tooltip']
           if 'Online' in state:
               online_states.append(True)
           else:
               online_states.append(False)
        return online_states
# Setup scheduler # Setup atexit # Called to update the stored information on the servers # Save old data # Get the page content and parse it # Extract the relevant divs # Parse into text # Collate the data # If update failed, restore old data # Log error # Returns the currently stored data dictionary # Parses server names from raw html # Parses server types from the raw html (Standard or Preferred) # If the server is offline this will return '--', set to an empty string # Parses character creation status from the raw html (True = CC Available, False = CC Unavailable) # An exception occurs when the server is offline, catch this and append false (no creation on an offline world) # Parses whether a server is online from the raw html (True = Online, False = Server offline)