예제 #1
0
def launch_rpc_debug():
    global RPC
    global start_time
    global running_title
    global rpc_running
    RPC = Presence(client_id)  # Initialize the client class
    RPC.connect()  # Start the handshake loop
    start_time = int(time.time())
    rpc_running = True
    running_title = debug_running_title

    while True:  # The presence will stay on as long as the program is running
        clear()

        title_info()
        get_icon()
        update_rpc()

        print("Rich Presence updated with the following information.\n")
        print("Status: " + details)
        print("Game Icon: " + large_image)
        if show_nnid == True:
            print("Nintendo Network ID: " + nnid)
        print("\nRich Presence is currently running in test mode.")
        print("\nUpdating again in 15 seconds.")
        print("\nPress Ctrl+C or close your terminal to stop.")

        time.sleep(15)  # Can only update rich presence every 15 seconds
예제 #2
0
class DiscordRPC:
    def __init__(self,
                 pipe=0,
                 loop=asyncio.get_event_loop(),
                 autoconnect=True):
        try:
            self.obj = Presence("757346500484268152", pipe=pipe, loop=loop)
            if autoconnect:
                self.obj.connect()
                log.info(
                    f"Successfully established a connection with Discord RPC! ({self.obj})"
                )
        except:
            raise Exception(
                0, "There was a problem while creating a Discord RPC object.")

    def connect(self):
        try:
            self.obj.connect()
        except:
            raise DiscordException(
                100, "There was a problem connecting a Discord RPC object.")

    def update(self, **kwargs):
        try:
            self.obj.update(
                **kwargs,
                **{x: y
                   for x, y in default_rpc.items() if x not in kwargs})
        except:
            raise DiscordException(
                300,
                "There was a problem while updating a Discord RPC object.")
def button_command():
    entry1.get()
    text = entry1.get()
    root.quit()
    try:
        while True:
            client_id = '819553518234107904'  #Put your client ID here
            RPC = Presence(client_id)
            RPC.connect()

            print(
                RPC.update(state="uzywajac MCmonitor",
                           details="Monitoruje swoj serwer",
                           large_image="logo",
                           small_image=" ",
                           large_text="Monitoruje swoj serwer MC!",
                           buttons=[{
                               "label": "Pobierz MC monitor!",
                               "url": "https://google.com"
                           }],
                           start=time.time()))  # Set the presence
            time.sleep(15)
            server = MinecraftServer.lookup(text)
            status = server.status()
            print("Na serwerze gra {0} graczy na pingu {1} ms".format(
                status.players.online, status.latency))
            sleep(2.00)
    except Exception:
        print("error")
        toaster = ToastNotifier()
        toaster.show_toast("Blad serwera!",
                           "Blad serwera!",
                           icon_path=None,
                           duration=60)
예제 #4
0
def discoPresence(client_id):
    RPC = Presence(client_id)
    RPC = Presence(client_id,pipe=0)

    RPC.connect()

    state = moc.get_info_dict()['state']
    if state == "PLAY":
        while True:
            artist = moc.get_info_dict()['artist']
            track = moc.get_info_dict()['songtitle']
            bitrate = moc.get_info_dict()['bitrate']
            rate = moc.get_info_dict()['rate']
            file = moc.get_info_dict()['file'].split('/')[-1]
            ext = file.split('.')[-1]
            
            if artist != "":
                print(RPC.update(details="Playing {:} - {:}".format(artist, track), state="{:} | {:} | {:}".format(bitrate, rate, ext)))
                sleep(5)

            else:
                print(RPC.update(details="{:}".format(file), state="{:} | {:}".format(bitrate, rate)))
                sleep(5)
    else:
        return
예제 #5
0
def initRichPresence():
    global RPC
    try:
        RPC = Presence(808045598447632384)
        RPC.connect()
    except:  # Discord not launched
        pass
예제 #6
0
class Ralsei(commands.Bot):
    def __init__(self, config):
        self.config = config
        super(Ralsei, self).__init__(
            command_prefix=config.command_prefix,
            description="""Ralsei, the Fluffiest Bot on Discord!""",
            case_insensitive=config.case_insensitive,
            pm_help=config.pm_help,
            command_not_found=config.command_not_found,
            command_has_no_subcommands=config.command_has_no_subcommands,
            owner_id=config.owner_id if (config.owner_id != "") else None,
            activity=discord.Activity(
                name="In an Unknown World",
                url="https://www.twitch.tv/discord_ralsei",
                type=discord.ActivityType.streaming))
        try:
            self.RPC = Presence(config.app_id)
            self.RPC.connect()
            self.RPC.update(start=int(time.time()),
                            details="in an Unknown World",
                            state="Most likely with Python",
                            large_image="ralsei_uh",
                            large_text="nothing to see here")
        except exceptions.InvalidPipe or FileNotFoundError:
            pass

    def ralsei_run(self):
        self.run(self.config.token)
예제 #7
0
class RichPressence:
    def __init__(self, client):
        self.rpc = Presence(client)  # Initialize the client class
        self.rpc.connect()  # Start the handshake loop

    def set_presence(self, pid, state, detail, large_image=None, starttime=None, limit=5):
        try:
            # while  True:
            if large_image and starttime:
                self.rpc.update(state=state, large_image=large_image, start=starttime, details=detail, pid=pid)  # Set the presence
            elif large_image:
                self.rpc.update(state=state, large_image=large_image, details=detail, pid=pid)  # Set the presence
            elif starttime:
                self.rpc.update(state=state, start=starttime, details=detail, pid=pid)  # Set the presence
            else:
                self.rpc.update(state=state, details=detail, pid=pid)  # Set the presence
                
                # time.sleep(limit)
        except Exception as e:
            print(e)
            self.rpc.close()  # close connection
            exit()

    def clear(self, pid):
        try:
            self.rpc.clear(pid)  # close connection
        except Exception as e:
            print(e)
            pass
예제 #8
0
class Discord:
    def __init__(self, id):
        self.id = id
        self.rpc = Presence(id)
        self.cleared = True
        self.rpc.connect()

    def clear(self):
        if self.cleared == False:
            print("Clearing status")
            self.rpc.clear()

        self.cleared = True

    def setTrack(self, track):
        print("Changing track to: " + track.track + " by " + track.artist + "(" + track.artist.lower().replace(' ', '_') + ")")
        self.cleared = False
        self.rpc.update(
            state="By " + track.artist,
            details=track.track,
            start=int(track.start),
            large_image=track.artist.lower().replace(' ', '_'),
            large_text="Apple Music",
            small_image="logo",
            small_text="github.com/leahlundqvist")
예제 #9
0
파일: bot.py 프로젝트: psychosub/Midas
async def on_ready():
    print("Online and Ready")
    status = discord.Activity(type=discord.ActivityType.playing, name="-help")
    await client.change_presence(activity=status)
    rpc = Presence("754666157826506794")
    rpc.connect()
    rpc.update(state="Example", details="Example", large_image="test", start=time.time())
예제 #10
0
class MyClass():
    def __init__(self, client_id):
        self.client_id = client_id
        self.RPC = Presence(self.client_id)

    def connect(self):
        try:
            self.RPC.connect()
            return True
        except Exception as e:
            print(str(e))
            return False

    def statusUpdate(self, state):
        try:
            self.RPC.update(details=state['details'],
                            state=state["state"],
                            start=state["startTimestamp"],
                            large_image=state['largeImageKey'],
                            large_text=state["largeImageText"],
                            small_image=state['smallImageKey'],
                            small_text=state["smallImageText"],
                            buttons=state["buttons"])
        except Exception as e:
            print(str(e))

    def close_presence(self):
        try:
            self.RPC.clear(pid=os.getpid())
        except Exception as e:
            print(str(e))
def run():
    APPLICATION_ID = "929437173764223057"
    RPC = Presence(APPLICATION_ID)
    RPC.connect()
    RPC.update(state="Alas is playing Azurlane",
               start=time.time(),
               large_image="alas")
예제 #12
0
def Run():
    client_id = '613783460699701278'
    RPC = Presence(client_id)
    RPC.connect()
    while True:
        time.sleep(15)
        RPC.update(state="Coding...", details="Editing command engine", start=1)
예제 #13
0
def discord():
	client_id = "574334562201501696"
	RPC = Presence(client_id)
	RPC.connect()

	while True:
		time.sleep(1)
		if os.popen("cmus-remote -Q | grep \"status \"").read() == "status stopped\n":
			artist = "  "
			title = "  "
			current_time = "IDLE"
			small_image = None
		else:
			artist = os.popen("cmus-remote -Q | grep \"tag artist\" | sed s/\"tag artist \"//").read()
			title = os.popen("cmus-remote -Q | grep \"tag title\" | sed s/\"tag title \"//").read()

			if os.popen("cmus-remote -Q | grep \"status \"").read() == "status paused\n":
				current_time = "(paused)"
				small_image = "pause"
			else:
				position = int(os.popen("cmus-remote -Q | grep \"position\" | sed s/\"position \"//").read())
				duration = int(os.popen("cmus-remote -Q | grep \"duration\" | sed s/\"duration \"//").read())
				current_time = " (" + str(position) + "/" + str(duration) + ")"
				small_image = "play"

		RPC.update(details=artist, state=title + current_time, large_image="logo", small_image=small_image)
예제 #14
0
def setup_discord():
    """
    Set up the discord rich presence client
    """
    rpc = Presence(credentials["discord"]["client_id"])
    rpc.connect()
    return rpc
예제 #15
0
def initRichPresence():
    global RPC
    try:
        RPC = Presence(808056068113563701)
        RPC.connect()
    except:  # Discord not launched
        pass
예제 #16
0
def run():
    presence = Presence(CLIENT_ID)
    presence.connect()
    while True:
        data = get_presence_data()
        presence.update(**data)
        time.sleep(15)
예제 #17
0
def rpc_process(conn, routes):
    large_icon = 'main_icon'

    client_id = "545357282880389141"  # Put your Client ID in here
    rpc = Presence(client_id)  # Initialize the Presence client
    current_route = "hanako"
    current_act = '1'
    connected = False
    while not connected:
        try:
            rpc.connect()  # Start the handshake loop
            connected = True
        except FileNotFoundError:
            connected = False
            print("Is Discord running?")
            time.sleep(5)
    start_time = int(time.time())

    rpc.update(start=start_time, state="In Game")  # Set's start time

    while True:  # The presence will stay on as long as the program is running
        if current_route in routes.keys():
            rpc_route = routes[current_route]
            rpc.update(details=rpc_route['details'],
                       large_image=rpc_route['image'],
                       small_image=large_icon,
                       large_text=rpc_route['details'],
                       start=start_time,
                       state="Act: {}".format(current_act))
        if conn.poll(5):
            received = conn.recv()
            if received[0]:
                current_route = received[0]
            if received[1]:
                current_act = received[1]
class DiscordRichPresence():
    def __init__(self, game):
        self.GAME = game
        self.__CHANNEL = 0

        # Set a date in the past
        self.LAST_CHANGED = 0

        self.UPDATE_EVERY = datetime.timedelta(
            seconds=120  # Every 2 Minutes
        ).total_seconds() * 500  # Grabs the milliseconds

        self.PYGAME_EVENT = pygame.event.Event(pygame.USEREVENT,
                                               Channel=self.CHANNEL)

        self.PYPRESENCE_CLIENT_ID = 790056166684229692  # Change this to whatever, it doesn't really matter
        self.RPC = Presence(self.PYPRESENCE_CLIENT_ID)
        self.RPC.connect()  # Connects to discord

    @property
    def CHANNEL(self):
        return self.__CHANNEL

    @CHANNEL.setter
    def CHANNEL(self, value):
        self.__CHANNEL = value

    def register_channel(self, eventno: int):
        print("Registering Channels...")
        pygame.time.set_timer(eventno, 500)
        self.CHANNEL = eventno
        print("Channel is set to `%s`" % self.CHANNEL)
        return eventno, self

    def get_state_text(self):
        if self.GAME.GAMESTATE == enums.GameState.playing:
            return "Currently Playing"
        elif self.GAME.GAMESTATE == enums.GameState.paused:
            return "Paused"
        elif self.GAME.GAMESTATE == enums.GameState.menu_screen:
            return "In Menus"

    def event_hook(self, event):
        self.update_presence()

    def update_presence(self):
        current_time = self.GAME.Ticker._clock.get_time()

        if self.LAST_CHANGED + self.UPDATE_EVERY < pygame.time.get_ticks(
        ) or self.LAST_CHANGED == 0:
            print(
                f'updating {self.LAST_CHANGED + self.UPDATE_EVERY} < {pygame.time.get_ticks()}'
            )
            # Since the game currently only supports gamestates, i'm going off of that.
            self.RPC.update(
                large_image="logo-holo",
                #details = __verison__,
                state=self.get_state_text())
            self.LAST_CHANGED = current_time
예제 #19
0
def start(process: psutil.Process, info: dict, *args: Any,
          **kwargs: Any) -> Presence:
    print(f"ゲームが {info['game_name']} に設定されました。RPCに接続します...")
    presence = Presence(info['client_id'])
    presence.connect()
    update(presence, process, info, *args, **kwargs)
    print('接続完了')
    return presence
예제 #20
0
def first_connect():
    try:
        client_id = appid
        RPC = Presence(client_id)
        RPC.connect()
        print("RPC Connection Successful.")
    except ConnectionRefusedError:
        rpc_tryconnect(RPC)
예제 #21
0
def initRichPresence():
    global RPC
    try:
        RPC = Presence(808056068113563701)
        RPC.connect()
        debugOutput("Discord rich presence initialized")
    except:  # Discord not launched
        pass
class gui():
    def __init__(self):
        config = loadConfig("config.ini", config=CONFIGDEFAULT)
        self.rungame = config["rungame.run"], config["rungame.path"], config[
            "rungame.args"], config["rungame.wait"]
        self.logger = log()
        self.watch = watch(config)
        self.RPC = Presence(535809971867222036)
        self.RPC.connect()
        self.main()

    def main(self):
        self.logger.debug("Start Main Loop")
        self.main_thread = True
        thread = threading.Thread(target=self.background, args=())
        thread.start()
        menu_def = ["BLANK", "Exit"]
        tray = sg.SystemTray(menu=menu_def,
                             filename='./elite-dangerous-clean.ico',
                             tooltip="Elite Dangerous Rich Presence")
        while self.main_thread is True:  # The event loop
            menu_item = tray.Read(timeout=15000)
            if menu_item == 'Exit':
                self.watch.mainThreadStopped()
                break
            data = self.watch.presenceUpdate()
            response = self.RPC.update(state=data["state"],
                                       details=data["details"],
                                       start=data["start"],
                                       large_text=data["large_text"],
                                       large_image=data["large_image"],
                                       party_size=data["party_size"])
            self.logger.debug(response)
        self.RPC.close()
        self.logger.debug("Main Loop Complete")

    def background(self):
        self.logger.debug("Check if the Game should be started")
        if self.watch.getGame() is False and self.watch.getLauncher(
        ) is False and self.rungame[0] is True:
            if os.path.exists(self.rungame[1]):
                self.logger.debug("Game Path exists")
                try:
                    self.logger.debug("Try to start game")
                    game = self.rungame[1] + " " + self.rungame[2]
                    subprocess.Popen(game)
                    time.sleep(int(self.rungame[3]))
                except Exception as e:
                    self.logger.error("Could not start Game: " + str(e))
            else:
                self.logger.warning("Game Path doesn't exists")
        self.logger.debug("Start Background Loop")
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
        loop.run_until_complete(self.watch.main())
        loop.close()
        self.main_thread = False
        self.logger.debug("Background Loop Complete")
예제 #23
0
 def connect():
     global RPC
     try:
         RPC = Presence(808045598447632384)
         RPC.connect()
         Thread(target=Discord_rp.update).start()
     except Exception as e:
         #print("Error launching Discord RPC thread: " + str(e))
         pass
예제 #24
0
def initRichPresence():
    global RPC
    try:
        RPC = Presence(808045598447632384)
        RPC.connect()
        debugOutput("Discord rich presence initialized")
    except:  # Discord not launched
        if debug == "y":
            raise
예제 #25
0
def initRichPresence():
    # Initialize Discord rich presence
    global RPC
    try:
        RPC = Presence(808045598447632384)
        RPC.connect()
        debugOutput("Discord rich presence initialized")
    except Exception as e:
        # Discord not launched
        debugOutput("Error launching Discord RPC thead: " + str(e))
예제 #26
0
파일: AVR_Miner.py 프로젝트: 0x43b/Gold
def init_rich_presence():
    # Initialize Discord rich presence
    global RPC
    try:
        RPC = Presence(808056068113563701)
        RPC.connect()
        debug_output("Discord rich presence initialized")
    except Exception:
        # Discord not launched
        pass
예제 #27
0
def awalan():
    id = int(input("Please put your Client ID: "))
    state1 = input("Put your state rpc: ")
    details = input("Put your Details rpc: ")
    limg = input("Put your large img name: ")
    simg = input("Put your small img name: ")
    client_id = f'{id}'
    RPC = Presence(client_id) 
    RPC.connect() 
    print(RPC.update(state=f"{state1}", details=f"{details}", large_image=f"{limg}", small_image=f"{simg}", large_text="NAME", start=time.time()))
예제 #28
0
def init_rich_presence():
    # Initialize Discord rich presence
    global RPC
    try:
        RPC = Presence(905158274490441808)
        RPC.connect()
        Thread(target=update_rich_presence).start()
    except Exception as e:
        #print("Error launching Discord RPC thread: " + str(e))
        pass
예제 #29
0
def main():

    VERSION = "1.1.0";

    config = GetConfig();

    mpdc = MPDClient();
    mpdc.timeout = int(config["General"]["MPDtimeout"]);
    mpdc.idletimeout = int(config["General"]["MPDtimeout_idle"]);
    try:
        mpdc.connect(config["General"]["MPDip"], port=int(config["General"]["MPDport"]));
    except ConnectionRefusedError:
        print(f"{TermColors.ERROR}ERROR!!! Either mpd isn't running or you have a mistake in the config. Fix ASAP! Exiting!{TermColors.END}");
        exit(-1);

    RPC = Presence(710956455867580427);
    RPC.connect();

    if (psys() == "Windows"):
        ossys("cls");
    else:
        ossys("clear");

    print(f"{TermColors.WORKS}MPDDRP v.{VERSION} - https://github.com/AKurushimi/mpddrp{TermColors.END}");

    try:
        while True:

            statusout = mpdc.status();
            csout = mpdc.currentsong();

            if (statusout["state"] != "stop"):
                title = csout["title"];
                artist = csout["artist"];
                album = csout["album"];
                timevar = statusout["time"].split(":");
                timenow = str(timedelta(seconds=int(timevar[0])));
                timeall = str(timedelta(seconds=int(timevar[1])));

            if (statusout["state"] == "pause"):
                RPC.update(details=title + " | " + album, state="Paused | " + artist, large_image="mpdlogo", small_image="pause", small_text="Paused");
            elif (statusout["state"] == "stop"):
                RPC.update(details="Stopped | MPD", state="   ", large_image="mpdlogo", small_image="stop", small_text="Stopped");
            elif (statusout["state"] == "play"):
                RPC.update(details=title + " | " + album, state=timenow + "/" + timeall + " | " + artist, large_image="mpdlogo", small_image="play", small_text="Playing");
                sleep(1);

    except (RuntimeError):
        pass;
    except (KeyboardInterrupt, SystemExit):
        RPC.clear();
        RPC.close();
        exit(0);
예제 #30
0
def RichPresence():
    if rich_presence == "y" or rich_presence == "Y":
        try:
            RPC = Presence("816053514584195073")
            RPC.connect()
            RPC.update(details="Connected",
                       large_image="averylarge2",
                       small_image="avery",
                       large_text="github.com/skeqt/AveryNuker",
                       start=time.time())
        except:
            pass
예제 #31
0
def RichPresence():
    if rich_presence == "y" or rich_presence == "Y":
        try:
            RPC = Presence("828547839994888192")
            RPC.connect()
            RPC.update(details="Connected",
                       large_image="multi_tool",
                       small_image="multi_tool",
                       large_text="Okuru Multi-Tool",
                       start=time.time())
        except:
            pass
예제 #32
0
class DiscordPresence(object):
    """This class provides rich presence integration
       with Discord for games.
    """

    def __init__(self):
        self.available = bool(PyPresence)
        self.game_name = ""
        self.runner_name = ""
        self.last_rpc = 0
        self.rpc_interval = 60
        self.presence_connected = False
        self.rpc_client = None
        self.client_id = None
        self.custom_game_name = ''
        self.show_runner = True
        self.custom_runner_name = ''
        self.rpc_enabled = True

    def load_from_config(self, config):
        """Loads
        """

    def ensure_discord_connected(self):
        """Make sure we are actually connected before trying to send requests"""
        logger.debug("Ensuring connected.")
        if self.presence_connected:
            logger.debug("Already connected!")
        else:
            logger.debug("Creating Presence object.")
            self.rpc_client = PyPresence(self.client_id)
            try:
                logger.debug("Attempting to connect.")
                self.rpc_client.connect()
                self.presence_connected = True
            except Exception as ex:
                logger.exception("Unable to reach Discord.  Skipping update: %s", ex)
                self.ensure_discord_disconnected()
        return self.presence_connected

    def ensure_discord_disconnected(self):
        """Ensure we are definitely disconnected and fix broken event loop from pypresence"""
        logger.debug("Ensuring disconnected.")
        if self.rpc_client is not None:
            try:
                self.rpc_client.close()
            except Exception as e:
                logger.exception("Unable to close Discord RPC connection: %s", e)
            if self.rpc_client.sock_writer is not None:
                try:
                    logger.debug("Forcefully closing sock writer.")
                    self.rpc_client.sock_writer.close()
                except Exception:
                    logger.exception("Sock writer could not be closed.")
            try:
                logger.debug("Forcefully closing event loop.")
                self.rpc_client.loop.close()
            except Exception:
                logger.debug("Could not close event loop.")
            try:
                logger.debug("Forcefully replacing event loop.")
                self.rpc_client.loop = None
                asyncio.set_event_loop(asyncio.new_event_loop())
            except Exception as e:
                logger.exception("Could not replace event loop: %s", e)
            try:
                logger.debug("Forcefully deleting RPC client.")
                self.rpc_client = None
            except Exception as ex:
                logger.exception(ex)
        self.rpc_client = None
        self.presence_connected = False

    def update_discord_rich_presence(self):
        """Dispatch a request to Discord to update presence"""
        if int(time.time()) - self.rpc_interval < self.last_rpc:
            logger.debug("Not enough time since last RPC")
            return
        if self.rpc_enabled:
            self.last_rpc = int(time.time())
            connected = self.ensure_discord_connected()
            if not connected:
                return
            try:
                state_text = "via %s" % self.runner_name if self.show_runner else "  "
                logger.info("Attempting to update Discord status: %s, %s",
                            self.game_name, state_text)
                self.rpc_client.update(details="Playing %s" % self.game_name, state=state_text)
            except PyPresenceException as ex:
                logger.error("Unable to update Discord: %s", ex)

    def clear_discord_rich_presence(self):
        """Dispatch a request to Discord to clear presence"""
        if self.rpc_enabled:
            connected = self.ensure_discord_connected()
            if connected:
                try:
                    logger.info('Attempting to clear Discord status.')
                    self.rpc_client.clear()
                except PyPresenceException as e:
                    logger.error("Unable to clear Discord: %s", e)
                    self.ensure_discord_disconnected()
예제 #33
0
class MainWindow(ThemedTk):
    """
    Child class of tk.Tk that creates the main windows of the parser.
    Creates all frames that are necessary for the various functions of
    the parser and provides exit-handling.
    """

    def __init__(self, raven: RavenClient):
        self.raven = variables.raven = raven
        self.width = 800 if sys.platform != "linux" else 825
        self.height = 425 if sys.platform != "linux" else 450
        # Initialize window
        ThemedTk.__init__(self)
        self.set_attributes()
        self.update_scaling()
        self.open_debug_window()
        self.finished = False
        variables.main_window = self
        self.style = ttk.Style()
        self.set_icon()
        self.set_variables()
        self.config_style()
        self.discord = DiscordClient()
        # Get the default path for CombatLogs and the Installation path
        self.default_path = variables.settings["parsing"]["path"]
        # Set window properties and create a splash screen from the splash_screen class
        self.withdraw()
        self.splash = BootSplash(self)
        self.splash.label_var.set("Building widgets...")
        self.protocol("WM_DELETE_WINDOW", self.exit)
        # Add a notebook widget with various tabs for the various functions
        self.notebook = ttk.Notebook(self, height=420, width=self.width)
        self.file_tab_frame = ttk.Frame(self.notebook)
        self.realtime_tab_frame = ttk.Frame(self.notebook)
        self.settings_tab_frame = ttk.Frame(self.notebook)
        self.characters_frame = CharactersFrame(self.notebook, self)
        self.file_select_frame = FileFrame(self.file_tab_frame, self)
        self.middle_frame = StatsFrame(self.file_tab_frame, self)
        self.ship_frame = ShipFrame(self.middle_frame.notebook)
        self.middle_frame.notebook.add(self.ship_frame, text="Ship")
        self.realtime_frame = RealTimeFrame(self.realtime_tab_frame, self)
        self.settings_frame = SettingsFrame(self.settings_tab_frame, self)
        self.builds_frame = BuildsFrame(self.notebook, self)
        self.toolsframe = ToolsFrame(self.notebook)
        self.strategies_frame = StrategiesFrame(self.notebook)
        self.chat_frame = ChatFrame(self.notebook, self)
        # Pack the frames and put their widgets into place
        self.grid_widgets()
        self.child_grid_widgets()
        # Add the frames to the Notebook
        self.setup_notebook()
        # Update the files in the file_select frame
        self.splash.label_var.set("Parsing files...")
        self.notebook.grid(column=0, row=0, padx=2, pady=2)
        self.file_select_frame.update_files()
        self.settings_frame.update_settings()
        # Check for updates
        self.splash.label_var.set("Checking for updates...")
        self.update()
        check_update()
        # Synchronize with Discord Bot Server
        if settings["sharing"]["enabled"] is True:
            self.splash.label_var.set("Synchronizing with Discord Bot Server...")
            self.update()
            self.discord.send_files(self)
        # Discord Rich Presence
        if settings["realtime"]["drp"] is True:
            self.rpc = Presence(436173115064713216)
            try:
                self.rpc.connect()
            except Exception:
                messagebox.showwarning("Error", "Discord Rich Presence failed to connect.")
                self.rpc = None
        else:
            self.rpc = None
        self.update_presence()
        # Give focus to the main window
        self.deiconify()
        self.finished = True
        self.splash.destroy()
        self.splash = None
        # Mainloop start (main.py)

    def update_presence(self):
        """Update to the basic GSF Parser presence"""
        if self.rpc is None:
            return
        assert isinstance(self.rpc, Presence)
        self.rpc.update(state="Not real-time results", large_image="logo_green_png")

    def grid_widgets(self):
        """Grid all widgets in the frames"""
        self.file_select_frame.grid(column=1, row=1, sticky="nswe")
        self.middle_frame.grid(column=2, row=1, sticky="nswe", padx=5, pady=5)
        self.realtime_frame.grid()
        self.settings_frame.grid()

    def child_grid_widgets(self):
        """Configure the child widgets of the Frames in grid geometry"""
        self.file_select_frame.grid_widgets()
        self.middle_frame.grid_widgets()
        self.realtime_frame.grid_widgets()
        self.ship_frame.grid_widgets()
        self.settings_frame.grid_widgets()
        self.builds_frame.grid_widgets()
        self.characters_frame.grid_widgets()
        self.toolsframe.grid_widgets()
        self.file_select_frame.clear_data_widgets()
        self.strategies_frame.grid_widgets()

    def setup_notebook(self):
        """Add all created frames to the notebook widget"""
        self.notebook.add(self.file_tab_frame, text="File parsing")
        self.notebook.add(self.realtime_tab_frame, text="Real-time parsing")
        self.notebook.add(self.chat_frame, text="Chat Logger")
        self.notebook.add(self.characters_frame, text="Characters")
        self.notebook.add(self.builds_frame, text="Builds")
        self.notebook.add(self.strategies_frame, text="Strategies")
        self.notebook.add(self.toolsframe, text="Tools")
        self.notebook.add(self.settings_tab_frame, text="Settings")

    def set_attributes(self):
        """
        Setup various window attributes:
        - Resizability
        - Window title
        - WM_DELETE_WINDOW redirect
        - DPI scaling
        - Screenshot functionality
        """
        self.resizable(width=False, height=False)
        self.wm_title("GSF Parser")
        self.protocol("WM_DELETE_WINDOW", self.exit)
        self.geometry("{}x{}".format(*self.get_window_size()))
        self.bind("<F10>", self.screenshot)

    @staticmethod
    def set_variables():
        """Set program global variables in the shared variables module"""
        variables.colors.set_scheme(variables.settings["gui"]["event_scheme"])

    def get_scaling_factor(self):
        """Return the DPI scaling factor (float)"""
        return self.winfo_pixels("1i") / 72.0

    def get_window_size(self):
        """Return the window size, taking scaling into account"""
        factor = self.winfo_pixels("1i") / 96.0
        size_x = int(self.width * factor)
        size_y = int(self.height * factor)
        return size_x, size_y

    def update_scaling(self):
        """Update the DPI scaling of the child widgets of the window"""
        self.tk.call('tk', 'scaling', '-displayof', '.', self.get_scaling_factor())

    def open_debug_window(self):
        """Open a DebugWindow instance if that setting is set to True"""
        if variables.settings["gui"]["debug"] is True:
            DebugWindow(self, title="GSF Parser Debug Window", stdout=True, stderr=True)
        return

    def config_style(self):
        """Configure the style: theme, font and foreground color"""
        # print("[MainWindow] PNG-based theme: {}".format(self.png_support))
        self.set_theme("arc")
        # print("[MainWindow] ThemedWidget Version: {}".format(getattr(self, "VERSION", None)))
        self.style.configure('.', font=("Calibri", 10))
        self.style.configure('TButton', anchor="w")
        self.style.configure('Toolbutton', anchor="w")
        self.style.configure('.', foreground=settings["gui"]["color"])
        self.setup_tk_toplevel_hooks()

    def setup_tk_toplevel_hooks(self):
        """Change the default background color of Tk and Toplevel"""
        color = self.style.lookup("TFrame", "background")
        self.config(background=color)
        __init__original = tk.Toplevel.__init__

        def __init__toplevel(*args, **kwargs):
            kwargs.setdefault("background", color)
            __init__original(*args, **kwargs)

        tk.Toplevel.__init__ = __init__toplevel

    def set_icon(self):
        """Changes the window's icon"""
        icon_path = os.path.join(get_assets_directory(), "logos", "icon_green.ico")
        icon = PhotoImage(Image.open(icon_path))
        self.tk.call("wm", "iconphoto", self._w, icon)

    def exit(self):
        """
        Function to cancel any running tasks and call any functions to
        save the data in use before actually closing the
        GSF Parser
        :return: SystemExit(0)
        """
        if self.destroy():
            sys.exit()

    def screenshot(self, *args):
        """Take a screenshot of the GSF Parser window and save"""
        x = self.winfo_x()
        y = self.winfo_y()
        result_box = (x, y, self.winfo_reqwidth() + x + 13, self.winfo_reqheight() + y + 15)
        file_name = os.path.join(
            get_temp_directory(),
            "screenshot_" + datetime.now().strftime("%Y-%m-%d_%H-%M-%S") + ".png")
        with mss() as sct:
            image = sct.grab(result_box)
        image = Image.frombytes("RGB", image.size, image.rgb)
        image.save(file_name)

    def destroy(self):
        """
        Destroy the MainWindow after checking for running processes

        Destroying the MainWindow is not allowed while connected to a
        Strategy Server or running one, the user will have to exit the
        server first.
        """
        if self.strategies_frame.settings is not None:
            if self.strategies_frame.settings.server:
                messagebox.showerror("Error", "You cannot exit the GSF Parser while running a Strategy Server.")
                return False
            if self.strategies_frame.settings.client:
                messagebox.showerror("Error", "You cannot exit the GSF Parser while connected to a Strategy Server.")
                return False
            self.strategies_frame.settings.destroy()
        if self.realtime_frame.parser is not None:
            if self.realtime_frame.parser.is_alive():
                self.realtime_frame.stop_parsing()
        ThemedTk.destroy(self)
        if self.rpc is not None:
            self.rpc.update()
            self.rpc.close()
        return True

    def report_callback_exception(self, exc, val, tb):
        """Redirect Exceptions in the mainloop to RavenClient"""
        if not os.path.exists("development"):
            self.raven.captureException()
        ThemedTk.report_callback_exception(self, exc, val, tb)