def run(): APPLICATION_ID = "929437173764223057" RPC = Presence(APPLICATION_ID) RPC.connect() RPC.update(state="Alas is playing Azurlane", start=time.time(), large_image="alas")
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")
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]
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())
def run(): presence = Presence(CLIENT_ID) presence.connect() while True: data = get_presence_data() presence.update(**data) time.sleep(15)
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))
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 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 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)
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)
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)
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 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
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
def thestart(client_id, API_KEY, API_SECRET, user): network = pylast.LastFMNetwork(API_KEY) user = network.get_user(user) RPC = Presence(client_id) RPC.connect() # Start the handshake loop RPC.update(state="Playing some music." ) # Initialize the message. Will get replaced very shortly. while True: # The presence will stay on as long as the program is running nowplaying = user.get_now_playing() nowplaying = str(nowplaying) RPC.update(state="Playing " + nowplaying + ".") time.sleep(1)
def RichPresence(): if rpresence.upper() == "y" or rpresence.lower() == "y": try: RPC = Presence("829084497655234571") RPC.connect() RPC.update(large_image="8", details="Cry with me?", buttons=[{ "label": "Github", "url": "https://github.com/7BZ" }], start=time.time()) except: pass
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
def drp(): print("Connecting to Discord for Rich Presence...\n") try: client_id = "694286426338099250" RPC = Presence(client_id) RPC.connect() RPC.update(state="Setting up RPAN stream...", large_image="icon", large_text="Made by u/IOnlyPlayAsDrif", start=int(time.time())) except: print( "Failed to connect to Discord, restart the program or try again later to get Rich Presence!" )
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)
class DiscordRP: def __init__(self): self.loadClientID() self.RPC = Presence(self.client_id) self.RPC.connect() def loadClientID(self): with open('auth.json') as json_file: d = json.load(json_file) self.client_id = d['client_id'] def updatePresence(self, info): options = { 'state': 'Origin {}'.format(info['app'][:info['app'].index('.')]), 'details': '{} by {}'.format(info['title'], info['album_artist']) } self.RPC.update(**options)
class Application(tk.Frame): 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 initial(self): tk.Label(self, text="State: ").grid(row=1) self.states = tk.Entry(self) tk.Label(self, text="Details: ").grid(row=2) self.details = tk.Entry(self) self.update_ = tk.Button(self, text="Update Presence", command=self.update_) self.states.grid(row=1, column=1) self.details.grid(row=2, column=1) self.update_.grid(row=3, column=2) def loop_rpc(self): self.rpc.update(details=self.detail, state=self.state, large_image="futabalargeimagekey") self.master.after(10, self.loop_rpc) def update_(self): try: self.error.pack_forget() self.correct.pack_forget() except: pass if not self.details.get() or not self.states.get(): self.error = tk.Label(text="Details and States cannot be empty!") return self.detail, self.state = self.details.get(), self.states.get() def on_exit(self): self.rpc.close() self.master.destroy()
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 main(): logging.basicConfig( datefmt="%H:%M:%S", level=logging.DEBUG, format="%(asctime)s %(levelname)-7s %(name)-7s %(message)s") logging.getLogger('asyncio').setLevel(logging.ERROR) with open('app_config.json') as f: app_config = json.load(f) client_id = app_config["client_id"] # we probably don't need the secret for this # secret = app_config["secret"] RPC = Presence(client_id) # Initialize the client class RPC.connect() # Start the handshake loop atexit.register(RPC.close) # Ensure it get's closed on exit # Get the Funimation process process = get_process('funimation') # TODO: check for none # There seems to be some...interesting permissions on the executable, # making it only spawnable by Ye Olde svchost. Will likely need to # open it the "canonical" way, whatever that is for UWP apps. # cmdline = process.cmdline() # logging.debug("Program cmdline: %s", ' '.join(cmdline)) # TODO: when I make it a service, just wait around for process to respawn when it dies while process.is_running(): try: episode_id, language = get_episode_id(process) except ValueError: logging.info("No episode playing") else: logging.debug("Episode ID: %s\tLanguage: %s", episode_id, language) details = "Watching episode " + episode_id state = "Language: " + language logging.debug( "Updating presence...\nPID %d\n" "Details %s\nState %s", process.pid, details, state) RPC.update(pid=process.pid, details=details, state=state) if DEBUG: # pprint(process.connections('all')) for conn in process.connections(): unique_ips.add((conn.raddr.ip, conn.raddr.port)) pprint(unique_ips) time.sleep(10)
def rich_presence(): global rpc, d if is_running("eurotrucks2.exe"): rpc = Presence("731909306256982028") large_image = 'untitled-1' rpc.connect() mult = 3.6 sp, _sp = 'km/h', 'km' elif is_running("amtrucks.exe"): rpc = Presence("743029516083134494") large_image = 'untitled-3' rpc.connect() mult = 2.24 sp, _sp = 'mph', 'mi' while True: try: speed = round(d["data"]["telemetry"]["truck"]["speed"] * mult) if d["data"]["telemetry"]["job"]["onJob"] is False: details = "🚚 Freeroaming" elif d["data"]["telemetry"]["job"]["onJob"] is True: details = "🚚 {} -> {} | {} km left".format( d["data"]["jobData"]["sourceCity"], d["data"]["jobData"]["destinationCity"], round(d["data"]["telemetry"]["navigation"]["distance"] / 1000)) if d["data"]["telemetry"]["game"]["isMultiplayer"] is True: state = "🌐 Multiplayer | {} {}".format(speed, sp) elif d["data"]["telemetry"]["game"]["isMultiplayer"] is False: state = "🌐 Singleplayer | {} {}".format(speed, sp) start = base.start_time small_text = "{} {} | {} {}".format( d["data"]["telemetry"]["truck"]["make"], d["data"]["telemetry"]["truck"]["model"], round(d["data"]["telemetry"]["truck"]["odometer"], 1), _sp) small_image = 'untitled-2' rpc.update(details=details, state=state, start=start, small_text=small_text, small_image=small_image, large_image=large_image) time.sleep(5) except Exception as _e: print(_e) break
class Discord: 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 start(self): self.RPC.connect() print("Connect to the app '" + self.idclient + "'") self.RPC.update(state=self.state, details=self.details, large_image="default.png") # Set the presence print("Default update")
def discordRP(): try: client_id = '518003254605643796' RPC = Presence(client_id) print("Connecting to Discord Rich Presence.") RPC.connect() print("Succesfully connnected!") except Exception as e: print("Couldn't connect to Discord Rich Presence, error: \n" + str(e)) while True: # The presence will stay on as long as the program is running try: mohaaserver = readMOHAA() serverinfo = getServerDetails(mohaaserver) RPC.update(state=serverinfo[1], details=serverinfo[0], large_image="moh_icon", small_image=serverinfo[1][:3], ) # Set the presence except Exception as e: print("Error[Discord]: " + str(e)) time.sleep(15)
def diTH(): global current_data connected = False while not connected: try: client_id = '932430232049832423324' # Fake ID, put your real one here RPC = Presence(client_id) # Initialize the client class RPC.connect() # Start the handshake loop connected = True except Exception as e: print(126) print(e) connected = False time.sleep(20) while True: # The presence will stay on as long as the program is running try: print("---cdata---") print(current_data) print("---Ecdata---") d = handler.handle(current_data) print(d) RPC.update(state=d["state"], details=d["details"], large_image=d["large_image"], small_image=d["small_image"], large_text=d["large_text"], small_text=d["small_text"], start=d["start"], end=d["end"]) time.sleep(15) # Can only update rich presence every 15 seconds except Exception as e: print(144) print(e) while not connected: try: client_id = '778926641333796885' # Fake ID, put your real one here RPC = Presence(client_id) # Initialize the client class RPC.connect() # Start the handshake loop connected = True except Exception as e: print(149) print(e) connected = False time.sleep(20)
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 refreshChecker(): asyncio.set_event_loop(asyncio.new_event_loop()) global RPC global oldState global client_id discordIDS = os.popen("wmic process where name='discord.exe' get processid").read( ).replace("ProcessId", "") discordPIDS = discordIDS.split("\n") discords = [] counter = 0 for i in discordPIDS: try: discords.append(int(i)) except: pass counter = counter + 1 oldChangedPID = discords[len(discords) - 1] while True: discordIDS = os.popen("wmic process where name='discord.exe' get processid").read( ).replace("ProcessId", "") discordPIDS = discordIDS.split("\n") discords = [] counter = 0 for i in discordPIDS: try: discords.append(int(i)) except: pass counter = counter + 1 newChangedPID = discords[len(discords) - 1] if oldChangedPID != newChangedPID: # asyncio.set_event_loop(asyncio.new_event_loop()) time.sleep(5) OLDRPC = RPC OLDRPC.close() RPC = Presence(client_id) RPC.connect() RPC.update( state=oldState, start=datetime.now().timestamp(), large_image="big" ) oldChangedPID = newChangedPID
class DPresence: 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 setInterval( self, func, time ): #Méthode permettant d'executer toutes les n secondes une autre fonction self.e = threading.Event() while not self.e.wait(time): func() def updatepresence(self): self.RPC.update(large_image="cow_full")
def cmd(): try: RPC = Presence("838621119799099433") RPC.connect() RPC.update(state="In commands module", details="About to input a command", large_image="pcfire", large_text="Made by Jaylen!", start=time.time(), buttons=[{ "label": "Download", "url": "https://google.com" }]) except Exception as e: print(e) ctypes.windll.kernel32.SetConsoleTitleW( f"Commands [BETA] Active Threads: {threading.activeCount()}") init(autoreset=True, convert=True) clear() print(f"{Fore.BLUE}[?] Available modules\n" f"iptools: Get info about ip and stuff ") while 1: module = input("< ") if module.lower() == "iptools": tasks.append("Iptools") clear() iptools_setup() if module.lower() == "tasks": show_tasks = ", ".join(tasks) print(f"{Fore.LIGHTBLUE_EX}Active tasks: {show_tasks}") if module.lower() == "geoip": pass #BETA if module.lower() == "kill": kill() else: print(f"{Fore.RED}[!] Not a command")
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)
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()