From d6d698227b4c1ba1004d371ab5fb35ec8024b5da Mon Sep 17 00:00:00 2001 From: Jesusaves Date: Mon, 5 Feb 2024 18:35:33 -0300 Subject: Update discord_rpc to 4.0 https://pypi.org/project/discord-rpc --- discord_rpc/connection/__init__.py | 0 discord_rpc/connection/ipc.py | 387 ------------------------------------- discord_rpc/connection/rpc.py | 175 ----------------- 3 files changed, 562 deletions(-) delete mode 100644 discord_rpc/connection/__init__.py delete mode 100644 discord_rpc/connection/ipc.py delete mode 100644 discord_rpc/connection/rpc.py (limited to 'discord_rpc/connection') diff --git a/discord_rpc/connection/__init__.py b/discord_rpc/connection/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/discord_rpc/connection/ipc.py b/discord_rpc/connection/ipc.py deleted file mode 100644 index bbb26a7..0000000 --- a/discord_rpc/connection/ipc.py +++ /dev/null @@ -1,387 +0,0 @@ -from __future__ import absolute_import -import errno -import logging -from ..codes import errorcodes -from ..util.utils import is_windows, range, get_temp_path, to_bytes, bytes, to_unicode, is_python3, is_callable -import struct -import sys -if is_windows(): - # we're going to have to do some ugly things, because Windows sucks - import ctypes - GENERIC_READ = 0x80000000 - GENERIC_WRITE = 0x40000000 - OPEN_EXISTING = 0x3 - INVALID_HANDLE_VALUE = -1 - PIPE_READMODE_MESSAGE = 0x2 - ERROR_FILE_NOT_FOUND = 0x2 - ERROR_PIPE_BUSY = 0xE7 - ERROR_MORE_DATA = 0xEA - BUFSIZE = 512 -else: - try: - from socket import MSG_NOSIGNAL - _msg_flags = MSG_NOSIGNAL - except ImportError: - _msg_flags = 0 - try: - from socket import SO_NOSIGPIPE - _do_sock_opt = True - except ImportError: - _do_sock_opt = False - import socket - import fcntl - from os import O_NONBLOCK - - -class BaseConnection(object): - """Generate IPC Connection handler.""" - # *nix specific - __sock = None - # Windows specific - __pipe = None - - __open = False - __logger = None - __is_logging = False - - def __init__(self, log=True, logger=None, log_file=None, log_level=logging.INFO): - if not isinstance(log, bool): - raise TypeError('log must be of bool type!') - if log: - if logger is not None: - # Panda3D notifies are similar, so we simply check if we can make the same calls as logger - if not hasattr(logger, 'debug'): - raise TypeError('logger must be of type logging!') - self.__logger = logger - else: - self.__logger = logging.getLogger(__name__) - log_fmt = logging.Formatter('[%(asctime)s][%(levelname)s] ' + '%(name)s - %(message)s') - if log_file is not None and hasattr(log_file, 'strip'): - fhandle = logging.FileHandler(log_file) - fhandle.setLevel(log_level) - fhandle.setFormatter(log_fmt) - self.__logger.addHandler(fhandle) - shandle = logging.StreamHandler(sys.stdout) - shandle.setLevel(log_level) - shandle.setFormatter(log_fmt) - self.__logger.addHandler(shandle) - self.__is_logging = True - - def log(self, callback_name, *args): - if self.__logger is not None: - if hasattr(self.__logger, callback_name) and is_callable(self.__logger.__getattribute__(callback_name)): - self.__logger.__getattribute__(callback_name)(*args) - - def __open_pipe(self, pipe_name, log_type='warning'): - """ - :param pipe_name: the named pipe string - :param log_type: the log type to use (default 'warning') - :return: opened(bool), try_again(bool) - """ - if not is_windows(): - self.log('error', 'Attempted to call a Windows call on a non-Windows OS.') - return - pipe = ctypes.windll.kernel32.CreateFileW(pipe_name, GENERIC_READ | GENERIC_WRITE, 0, None, OPEN_EXISTING, 0, - None) - if pipe != INVALID_HANDLE_VALUE: - self.__pipe = pipe - return True, False - err = ctypes.windll.kernel32.GetLastError() - if err == ERROR_FILE_NOT_FOUND: - self.log(log_type, 'File not found.') - self.log(log_type, 'Pipe name: {}'.format(pipe_name)) - return False, False - elif err == ERROR_PIPE_BUSY: - if ctypes.windll.kernel32.WaitNamedPipeW(pipe_name, 10000) == 0: - self.log(log_type, 'Pipe busy.') - return False, False - else: - # try again, should be free now - self.log('debug', 'Pipe was busy, but should be free now. Try again.') - return False, True - # some other error we don't care about - self.log('debug', 'Unknown error: {}'.format(err)) - return False, False - - def open(self, pipe_no=None): - if pipe_no is not None: - if not isinstance(pipe_no, int): - raise TypeError('pipe_no must be of type int!') - if pipe_no not in range(0, 10): - raise ValueError('pipe_no must be within range (0 <= pipe number < 10)!') - if is_windows(): - # NOTE: don't forget to use a number after ipc- - pipe_name = u'\\\\.\\pipe\\discord-ipc-{}' - if pipe_no is not None: - # we only care about the first value if pipe_no isn't None - opened, try_again = self.__open_pipe(pipe_name.format(pipe_no)) - if opened: - self.__open = True - self.log('info', 'Connected to pipe {}, as user requested.'.format(pipe_no)) - return - elif try_again: - self.open(pipe_no=pipe_no) - return - else: - num = 0 - while True: - if num >= 10: - break - opened, try_again = self.__open_pipe(pipe_name.format(num), log_type='debug') - if opened: - self.__open = True - self.log('debug', 'Automatically connected to pipe {}.'.format(num)) - return - if try_again: - continue - num += 1 - # we failed to get a pipe - self.__pipe = None - self.log('warning', 'Could not open a connection.') - else: - self.__sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) - if self.__sock is None or self.__sock == -1: - self.log('warning', 'Could not open socket.') - self.close() - return - try: - fcntl.fcntl(self.__sock, fcntl.F_SETFL, O_NONBLOCK) - except Exception as e: - self.log('warning', e) - self.close() - return - if _do_sock_opt: - try: - socket.setsockopt(socket.SOL_SOCKET, SO_NOSIGPIPE) - except Exception as e: - self.log('warning', e) - self.log('debug', 'Attempting to use sock as is. Notify a developer if an error occurs.') - sock_addr = get_temp_path() - if sock_addr.endswith('/'): - sock_addr = sock_addr[:-1] - sock_addr += '/discord-ipc-{}' - if pipe_no is not None: - ret_val = self.__sock.connect_ex(sock_addr.format(pipe_no)) - if ret_val == 0: - self.__open = True - self.log('info', 'Connected to socket {}, as user requested.'.format(pipe_no)) - return - else: - self.log('warning', 'Could not open socket {}.'.format(pipe_no)) - self.close() - else: - for num in range(0, 10): - ret_val = self.__sock.connect_ex(sock_addr.format(num)) - if ret_val == 0: - self.__open = True - self.log('debug', 'Automatically connected to socket {}.'.format(num)) - return - self.log('warning', 'Could not open socket.') - self.close() - - def write(self, data, opcode): - if not self.connected(): - self.log('warning', 'Cannot write if we aren\'t connected yet!') - return False - if not isinstance(opcode, int): - raise TypeError('Opcode must be of int type!') - if data is None: - data = '' - try: - data = to_bytes(data) - except Exception as e: - self.log('warning', e) - return False - data_len = len(data) - # the following data must be little endian unsigned ints - # see: https://github.com/discordapp/discord-rpc/blob/master/documentation/hard-mode.md#notes - header = struct.pack('