def setup_discord(): """ Set up the discord rich presence client """ rpc = Presence(credentials["discord"]["client_id"]) rpc.connect() return rpc
def initRichPresence(): global RPC try: RPC = Presence(808045598447632384) RPC.connect() except: # Discord not launched pass
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)
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
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)
def initRichPresence(): global RPC try: RPC = Presence(808056068113563701) RPC.connect() except: # Discord not launched pass
def run(self): TrayApp.TrayApp(self.open_settings_call, name="Elite Dangerous Rich Presence", icon="elite-dangerous-clean.ico") logger.debug("Starting Rich Presence") self.rpc = Presence(535809971867222036) self.rpc.connect() # elite dangerous auto launch if self.config["elite_dangerous"]["auto_launch"] and os.path.exists( self.config["elite_dangerous"]["path"]): self.launch_ed() logger.debug("Preparing Tray Application") journal_parent_con, journal_child_con = Pipe() journal_app = Process(target=open_journal, args=(journal_child_con, self.config["general"]["journal_path"])) journal_app.start() logger.debug("Tray Application stated, continuing") logger.debug("Preparing Settings Window") self.settings_parent_con, settings_child_con = Pipe() app_settings = Process(target=open_settings, args=(settings_child_con, )) if not self.config["general"]["auto_tray"]: app_settings.start() logger.debug("Prepared Settings Window") code = 0 game = True logger.info("Entering main loop") while code == 0 and game: code = win32gui.PumpWaitingMessages() if self.open_settings and not app_settings.is_alive(): logger.debug("Opening Settings") app_settings.start() if self.settings_parent_con.poll(): msg = self.settings_parent_con.recv() if msg == "closed": app_settings = Process(target=open_settings, args=(settings_child_con, )) self.open_settings = False elif msg == "changed_settings": logger.debug("Config changed, reloading") self.load_config() if journal_parent_con.poll(): msg = journal_parent_con.recv() game = self.event_processing(msg) time.sleep(0.1) self.settings_parent_con.send("closed") journal_parent_con.send("closed")
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
def __init__(self): self.RPC = Presence(client_id=client_id) try: self.RPC.connect() self.updatepresence() start_new_thread(self.setInterval, (self.updatepresence, 15)) except: print("[WARNING] Discord not connected")
def initRichPresence(): global RPC try: RPC = Presence(808056068113563701) RPC.connect() debugOutput("Discord rich presence initialized") except: # Discord not launched pass
def __init__(self): self.idclient = '724944148238565416' self.details = "default" self.state = "Développée par BeeWildz#0101" self.RPC = Presence(self.idclient) self.L_image = "" self.S_image = ""
def setRPC(self): self.RPC = Presence(CLIENTID) self.RPC.connect() self.RPC.update(large_image="logom", large_text="Vagus Player", state=f"Boşta", start=time() * 1000)
def first_connect(): try: client_id = appid RPC = Presence(client_id) RPC.connect() print("RPC Connection Successful.") except ConnectionRefusedError: rpc_tryconnect(RPC)
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
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")
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
def initRichPresence(): global RPC try: RPC = Presence(808045598447632384) RPC.connect() debugOutput("Discord rich presence initialized") except: # Discord not launched if debug == "y": raise
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 __init__(self): super(UserInterface, self).__init__() print("Setting up the window...") self.setupUi(self) print("Loading settings window...") self.settingsWindow = Settings_UserInterface() self.settings_button.clicked.connect(self.openSettings) self.settingsWindow.onClose.connect(self.onSettingsClosed) print("Loading configuration...") json_file = open("data/config.json", "r") self.config_json = json.load(json_file) json_file.close() print("Loading languages...") json_file = open("data/translation.json", "r", encoding="UTF-8") self.translation = json.load(json_file) json_file.close() print("Initializing the presence...") client_id = self.config_json["App_ID"] self.RPC = Presence(client_id) print("Connecting...") self.RPC.connect() print("Ready") self.language = self.config_json["user_language"] self.l_format = self.translation[self.language]["format"] self.isRunning = False self.infos = {} self.confirm_button.clicked.connect(self.on_confirm_button_clicked) self.confirm_button.setText(self.translation[self.language]["confirm"]) self.title_label.setText(self.translation[self.language]["enter url"]) self.settings_button.setText( self.translation[self.language]["settings"]) self.scrollView = AnimeScrollView() self.setFocusPolicy(Qt.StrongFocus) self.scrollView.clicked.connect(self.onLabelClick) self.urlLayout.addWidget(self.scrollView) self.url_entry.focusOutEvent = lambda event: self.handleFocus("exit") self.url_entry.setPlaceholderText( self.translation[self.language]["enter url"]) self.url_entry.focusInEvent = lambda event: self.handleFocus("enter") self.url_entry.textEdited.connect(self.onEdit) self.scrollView.hide() self.fetcher = None self.choice = WebsiteComboBox(self.translation[self.language]) self.urlLayout.addWidget(self.choice) self.choice.hide()
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
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()))
def _initialize_rpc(self, app_id: str): """ Initializes the connection to Discord RPC. :param app_id: The app ID that will be used for RPC """ if self._rpc: self._rpc.close() self._rpc = Presence(app_id) self._rpc.connect() self._current_app_id = app_id
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
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))
def run(self): try: self.RPC = Presence( int( bytearray.fromhex( '363233383936373835363035333631363634').decode())) self.RPC.connect() except (InvalidPipe): self.DRPCisEnabled = False else: self.DRPCisEnabled = True while (not self.isStopped): if True: if (self.timeBuffer == 5): nameList = "" nbDof = 0 namePerso = self.__countWindows() sizePerso = len(namePerso) if sizePerso >= 1: for i in range(sizePerso): if not "Dofus" in namePerso[i][0]: nameList += namePerso[i][0] nbDof += 1 if not i == sizePerso - 1: nameList += ", " else: nameList = "Se connecte..." else: nameList = "Se connecte..." self.timeBuffer = 0 else: self.timeBuffer += 1 modifier = "" if config["General"]["retro_mode"] == "True": modifier = "retro" message = "Joue avec 0 comptes :" if nbDof > 1 or nbDof == 0: message = "Joue avec {0} comptes {1} :".format( nbDof, modifier) else: message = "Joue avec 1 compte {0} :".format(modifier) self.RPC.update(details=message, \ large_image="header", \ small_image="dofuslogo", \ small_text="Dofus", \ state=nameList, \ start=self.startTime) else: # En cas de déconnexion self.run() self.DRPCisEnabled = False sleep(1)
def __init__(self): super().__init__() self.vbox = virtualbox.VirtualBox() self.config = configparser.ConfigParser() self.config.read("config.ini") self.assets = json.load(open("assets.json", "r")) self.previous_formatdict = None client_id = self.config["Rich Presence"]["client_id"] self.RPC = Presence(client_id) self.RPC.connect() self.start_time = time.time() print("presence started") while True: if ( "VirtualBox.exe" in (p.name() for p in psutil.process_iter()) or "VirtualBoxVM.exe" in (p.name() for p in psutil.process_iter()) ) and (sys.platform.startswith("win32")): pvars = self.presence_gen() # print("-------------------------\npresence_dict\n-------------------------") # pprint.pprint(pvars) self.RPC.update( large_image=pvars["large_image"], large_text=pvars["large_text"], small_image=pvars["small_image"], small_text=pvars["small_text"], details=pvars["details"], state=pvars["state"], start=pvars["start"], ) if self.config["Rich Presence"]["debug"] == "true": pprint.pprint(pvars) print("--------------------") elif sys.platform.startswith("win32"): print("VirtualBox is not running") self.RPC.clear() else: pvars = self.presence_gen() # print("-------------------------\npresence_dict\n-------------------------") # pprint.pprint(pvars) self.RPC.update( large_image=pvars["large_image"], large_text=pvars["large_text"], small_image=pvars["small_image"], small_text=pvars["small_text"], details=pvars["details"], state=pvars["state"], start=pvars["start"], ) if self.config["Rich Presence"]["debug"] == "true": pprint.pprint(pvars) print("--------------------") time.sleep(15)
def __init__(self, master=tk.Tk()): super().__init__(master) self.master = master self.master.protocol("WM_DELETE_WINDOW", self.on_exit) self.rpc = Presence(CLIENT_ID, pipe=0) self.rpc.connect() self.detail, self.state = "Custom Presence", "Launching!" self.initial() self.pack() self.loop_rpc()
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 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]
def __init__(self): self.secondsuntilrestart = 3600 # this is how many seconds until the bot will restart. This is to stop the bot from crashing. Decrease this if you have crashes. self.xpamount = 0 # how much xp the bot has earnt during runtime self.restarted = 0 # how many times the bot has restarted during runtime self.gamesplayed = 0 # num of games played during runtime self.version = "Valbot v1.8.1" # variable str to change valbot version name in outputs self.foundwebhook = False title = "title " + self.version os.system(title) os.system('mode con: cols=54 lines=18') if os.path.exists("webhook.config"): try: f = open('webhook.config', 'r') self.hookline = f.readline() f.close() self.foundwebhook = True except Exception: self.foundwebhook = False try: # if cant connect to discord (if it isnt open for example), bot doesnt crash self.RPC = Presence( client_id="772841390467711041") # discord rpc client id try: self.RPC.close() except Exception: pass self.RPC.connect() # connects to rpc except Exception: pass print( Fore.RED + """ ╔╗ ╔╗╔═══╗╔╗ ╔══╗ ╔═══╗╔════╗ ║╚╗╔╝║║╔═╗║║║ ║╔╗║ ║╔═╗║║╔╗╔╗║ ╚╗║║╔╝║║ ║║║║ ║╚╝╚╗║║ ║║╚╝║║╚╝ ║╚╝║ ║╚═╝║║║ ╔╗║╔═╗║║║ ║║ ║║ ╚╗╔╝ ║╔═╗║║╚═╝║║╚═╝║║╚═╝║ ║║ ╚╝ ╚╝ ╚╝╚═══╝╚═══╝╚═══╝ ╚╝ """ + Style.NORMAL + Fore.RED, self.version.replace("Valbot ", "") + Style.RESET_ALL) print(Style.RESET_ALL) print(Style.RESET_ALL + Fore.RED + " By Fums & WolfAnto") print(Style.RESET_ALL) print(Style.RESET_ALL + Fore.RED + "——————————————————————————————————————————————————————")
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
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
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()
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
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)