def viewNotif(): Logger.log('User acknowledged notification.') self.clear() notifIcon.place_forget() self.notificationTitle = Label(self.Window, text=notifTitle, bg=self.WINDOW_BACKGROUND, fg=notifCol, font=('Calibri', 14, 'bold italic'), height=1, width=31, anchor='w') self.notificationTitle.place(relx=.05, rely=.3) self.notificationBox = Text(self.Window, bd=0, width=65, height=6, bg=self.WINDOW_BACKGROUND) self.notificationBox.place(relx=.055, rely=.4) self.notificationBox.insert(END, notifText) self.notificationBox.tag_add("!", 1.0, 99999999999999.0) self.notificationBox.tag_config("!", foreground=self.WINDOW_CHAT_BACKGROUND, font=('Segoe UI', 10, "bold italic"), spacing1='5', spacing2='5') self.notificationBox.config(state=DISABLED) self.notificationConfirm = Button(self.Window, text='CONFIRM', font=('Segoe UI', 10, "bold"), bg=self.WINDOW_BACKGROUND, fg=notifCol, bd=0, height=1, command=lambda: (self.notificationBox.place_forget(), self.notificationTitle.place_forget(), self.notificationConfirm.place_forget(), self.set(self.pageNumber), notifIcon2.place_forget())) self.notificationConfirm.place(relx=.78, rely=.85) notifIcon2 = Button(self.Window, text='!', font=('Segoe UI', 15, "bold"), bg='#141414', fg=notifCol, bd=0, width=4, height=1, command=lambda: (self.notificationBox.place_forget(), self.notificationTitle.place_forget(), self.notificationConfirm.place_forget(), self.set(self.pageNumber), notifIcon2.place_forget())) notifIcon2.place(relx=.9, rely=.05)
def refreshlist(self): if self.gotLobbyData: Logger.log('Received lobby data from game server.') lobbyNameLabel = Label(self.Window, text=str(self.lobbyStatName).upper(), fg=self.WINDOW_CHAT_BACKGROUND, bg=self.WINDOW_BACKGROUND, font=self.WINDOW_SUB_FONT3) lobbyGameLabel = Label(self.Window, text=str(self.lobbyStatGame).upper(), fg=self.WINDOW_CHAT_BACKGROUND, bg=self.WINDOW_BACKGROUND, font=self.WINDOW_SUB_FONT3) lobbyPlayersLabel = Label(self.Window, text=str(self.lobbyStatPlayers + ' PLAYERS').upper(), fg=self.WINDOW_CHAT_BACKGROUND, bg=self.WINDOW_BACKGROUND, font=self.WINDOW_SUB_FONT3) lobbyReadyLabel = Label(self.Window, text=str(self.lobbyStatReady + ' READY').upper(), fg=self.WINDOW_CHAT_BACKGROUND, bg=self.WINDOW_BACKGROUND, font=self.WINDOW_SUB_FONT3) lobbyNameLabel.place(relx=.45, rely=.3) lobbyGameLabel.place(relx=.45, rely=.4) lobbyPlayersLabel.place(relx=.45, rely=.5) lobbyReadyLabel.place(relx=.45, rely=.6) lName = Label(self.Window, text='LOBBY NAME', fg=self.WINDOW_THEME3, bg=self.WINDOW_BACKGROUND, font=self.WINDOW_BUTTON_FONT) lName.place(relx=.05, rely=.3) lGame = Label(self.Window, text='LOBBY GAME', fg=self.WINDOW_THEME3, bg=self.WINDOW_BACKGROUND, font=self.WINDOW_BUTTON_FONT) lGame.place(relx=.05, rely=.4) lPlayers = Label(self.Window, text='PLAYERS', fg=self.WINDOW_THEME3, bg=self.WINDOW_BACKGROUND, font=self.WINDOW_BUTTON_FONT) lPlayers.place(relx=.05, rely=.5) lReady = Label(self.Window, text='READY', fg=self.WINDOW_THEME3, bg=self.WINDOW_BACKGROUND, font=self.WINDOW_BUTTON_FONT) lReady.place(relx=.05, rely=.6) else: Logger.log('No lobby data was retrieved - list is empty.', 'WARNING') lUnavailable = Label(self.Window, text='There are no lobbies available this time.', fg=self.WINDOW_CHAT_BACKGROUND, bg=self.WINDOW_BACKGROUND, font=self.WINDOW_SUB_FONT2) lUnavailable.place(relx=.05, rely=.3)
def connect(self): try: self.gameSocket.connect((self.IP, self.PORT)) except: self.notify('Connection error', 'The client failed to connect to the game server, so some features such as lobbies and game statistics will be unavailable. ' 'You could try reconnecting or changing the server address below.', '#e74c3c') self.chat('ERROR: Failed to connect to relay server\n') Logger.log('Failed to connect to the game server.', 'ERROR')
def host(self): self.clear() self.gameState = 'HOST' self.hostCode = self.generate() self.hostButton.place(relx=.05, rely=.27) self.codeLabel.place(relx=.054, rely=.41) self.codeInfo.place(relx=.054, rely=.58) self.codeLabel.config(text=self.hostCode) Logger.log(f'Set game state to \'{self.gameState}\'.')
def decide(self, perception: NOMINAL_SENSOR) -> NOMINAL_MOTOR: Logger.log( f"\nController {id(self):d} perceives:\n{str(perception):s}") action = input(f"Target action {self._space_string:s}: ") while action not in self._motor_space: action = input( f"Action {action:s} is not among {self._space_string}. Try again: " ) return action
def front(self): self.gameState = 'MAIN' self.clear() self.hostButton.place(relx=.05, rely=.27) self.hostInfo.place(relx=.054, rely=.38) self.joinButton.place(relx=.05, rely=.47) self.joinInfo.place(relx=.054, rely=.58) self.browseButton.place(relx=.05, rely=.67) self.browseInfo.place(relx=.054, rely=.78) Logger.log(f'Set game state to \'{self.gameState}\'.')
def initialize(axes: Sequence[str], no_experiments: int, length: int = 0): status, json_response = initialize(tuple( (_name, no_experiments) for _name in axes), length=length) Logger.log(f"{status:d}\n{json_response:s}") axis_styles = dict() plot_styles = dict() status, json_response = style(axis_styles, plot_styles) Logger.log(f"{status:d}\n{json_response:s}")
def join(self): def sendcode(event): self.joinmatch() self.clear() self.gameState = 'JOIN' self.joinButton.place(relx=.05, rely=.27) self.codeEntry.place(relx=.055, rely=.41) self.entryInfo.place(relx=.055, rely=.58) self.codeEntry.focus_force() self.codeEntry.bind('<Return>', sendcode) Logger.log(f'Set game state to \'{self.gameState}\'.')
def broadcast(self, message): global tempMsg try: for connectedSocket in self.LIST: if connectedSocket != self.serverSocket: connectedSocket.send(str.encode(message)) if message != tempMsg: Logger.log(message.rstrip().lstrip(), 'BROADCAST') tempMsg = message except Exception as error: Logger.error(error)
def style(): data = request.data Logger.log(f"styling {str(data):s}") d = json.loads(data) VisualizationView._axis_styles.clear() VisualizationView._axis_styles.update(d["axes"]) VisualizationView._plot_styles.clear() VisualizationView._plot_styles.update(d["plots"]) return jsonify("styling done")
def _base_transfer(self, source_currency: int, amount: float, target_currency: int, rate: float) -> float: assert 0. < amount assert 0. < rate assert source_currency == 0 or target_currency == 0 current_value = self._values[source_currency] if current_value < amount: Logger.log("not enough of currency") return 0. self._values[source_currency] -= current_value received_value = current_value * self._fee_factor * rate self._values[target_currency] += received_value return received_value
def add_data(): if VisualizationView._model is None: raise ValueError("visualization model not initialized") data = request.data Logger.log(f"adding batch") d = json.loads(data) batch = d["batch"] iteration = d["iteration"] VisualizationView._model.add_batch(iteration, batch) return jsonify(f"added batch of size {len(batch):d}")
def refresh(self): for label in self.playerLabels: label.config(text='--') for player in self.gamePlayers: pIndex = self.gamePlayers.index(player) self.playerLabels[pIndex].config(text=player) for player in self.readyPlayers: rIndex = self.gamePlayers.index(player) self.readyLabels[rIndex].config(fg='#2ecc71') for player in self.gamePlayers: rIndex = self.gamePlayers.index(player) if player not in self.readyPlayers: self.readyLabels[rIndex].config(fg='#e74c3c') self.lobbyPlayers.config(text='Players currently connected [{0}/4]'.format(len(self.gamePlayers))) Logger.log('Refreshed window layout.')
class Wrapper: def __init__(self, error_messages, modules, p_schedule): self.__error_messages = error_messages self.__modules = modules self.__p_schedule = p_schedule self.__process = '' self.__logger = Logger() def commander(self, command, args): ''' auto (hour[0]): automatic video processing (download, encode, edit, upload, tweet) stop: stops auto mode ''' if command == 'auto': filter = self.__filter(args, 1) if filter: t = int(args[0]) print('Initializing auto clipper....') self.__logger.log('Initializing auto clipper, waiting till {}'.format(t)) self.__process = multiprocessing.Process(target=_auto, args=(self.__modules, self.__p_schedule, t, self.__p_tweets)) self.__process.start() return True elif command == 'stop': filter = self.__filter(args, 0) if filter: if self.__process: self.__process.terminate() self.__process = None print('Clipper auto mode stopped') else: print('Clipper is not running in auto mode') return True return False def __filter(self, args, ammount): if len(args) >= ammount: return True else: print(ConsoleColors.RED + 'Error: {0}'.format(self.__error_messages[0]) + ConsoleColors.RESET)
def set(self, page): Logger.log('Set current window page to \'{0}\'.'.format(self.pageNumber)) self.pageNumber = page if page == 1: self.front() elif page == 2: self.host() elif page == 3: self.join() elif page == 4: self.lobby() elif page == 5: self.game() if page == 1 or page == 4: self.backButton.place_forget() else: self.backButton.place(relx=.05, rely=.84)
def notify(self, err_name, err_info, err_col): Logger.log('Spawned notification symbol \'{0}\'.'.format(err_name)) notifTitle = err_name notifText = err_info notifCol = err_col # notifTitle = 'Update available' # notifText = 'You are not on the latest version of the client. Press update to download the latest project version from GitHub. Current files will be stored in a BACKUP ZIP file.\nCurrent Version: 4.70\nLatest Version: 4.71' # notifCol = '#f39c12' # notifTitle = 'Invalid configuration' # notifText = 'An invalid configuration file was detected. A new configuration file has been generated with default settings, to update these settings click your username' # notifCol = '#f39c12' def viewNotif(): Logger.log('User acknowledged notification.') self.clear() notifIcon.place_forget() self.notificationTitle = Label(self.Window, text=notifTitle, bg=self.WINDOW_BACKGROUND, fg=notifCol, font=('Calibri', 14, 'bold italic'), height=1, width=31, anchor='w') self.notificationTitle.place(relx=.05, rely=.3) self.notificationBox = Text(self.Window, bd=0, width=65, height=6, bg=self.WINDOW_BACKGROUND) self.notificationBox.place(relx=.055, rely=.4) self.notificationBox.insert(END, notifText) self.notificationBox.tag_add("!", 1.0, 99999999999999.0) self.notificationBox.tag_config("!", foreground=self.WINDOW_CHAT_BACKGROUND, font=('Segoe UI', 10, "bold italic"), spacing1='5', spacing2='5') self.notificationBox.config(state=DISABLED) self.notificationConfirm = Button(self.Window, text='CONFIRM', font=('Segoe UI', 10, "bold"), bg=self.WINDOW_BACKGROUND, fg=notifCol, bd=0, height=1, command=lambda: (self.notificationBox.place_forget(), self.notificationTitle.place_forget(), self.notificationConfirm.place_forget(), self.set(self.pageNumber), notifIcon2.place_forget())) self.notificationConfirm.place(relx=.78, rely=.85) notifIcon2 = Button(self.Window, text='!', font=('Segoe UI', 15, "bold"), bg='#141414', fg=notifCol, bd=0, width=4, height=1, command=lambda: (self.notificationBox.place_forget(), self.notificationTitle.place_forget(), self.notificationConfirm.place_forget(), self.set(self.pageNumber), notifIcon2.place_forget())) notifIcon2.place(relx=.9, rely=.05) notifIcon = Button(self.Window, text='!', font=('Segoe UI', 15, "bold"), bg='#141414', fg=notifCol, bd=0, width=4, height=1, command=lambda: viewNotif()) notifIcon.place(relx=.9, rely=.05)
def init_model(): data = request.data Logger.log(f"initializing {str(data):s}") d = json.loads(data) axes = d["axes"] VisualizationView._dist_axes = {_axis_name for _axis_name, _, _is_dist in axes if _is_dist} VisualizationView._axis_styles.clear() VisualizationView._plot_styles.clear() VisualizationView.length = d.get("length", 0) axes_model = tuple((_axis_name, _width) for _axis_name, _width, _ in axes) VisualizationView._model = VisualizationModel(axes_model, length=VisualizationView.length) VisualizationView._dash.layout = get_layout() _iterations = 0 return jsonify(f"initialized {str(axes):s}, length {VisualizationView.length:d}")
def listen(self): while True: try: read_sockets, write_sockets, error_sockets = select.select( self.LIST, [], []) for sock in read_sockets: if sock == self.gameSocket: sockfd, address = self.gameSocket.accept() self.LIST.append(sockfd) Logger.log( f'Client [{address[0]}:{address[1]}] connected to the server.', 'CONNECT') else: try: receivedData = sock.recv(40, ).decode() except: try: try: disconnected_user = self.connectedUsers[ address] del self.connectedUsers[address] except: disconnected_user = '******' Logger.log( f'Client [{address[0]}:{address[1]}] ({disconnected_user}) disconnected from the server.', 'DISCONNECT') except Exception as error: Logger.error(error) sock.close() self.LIST.remove(sock) continue if receivedData: arguments = receivedData.split(';') if arguments[0] != str(self.randomID): if arguments[1] == str( self.gameInstance.getPage()): self.otherPlayer.setLocation( round(float(arguments[2]), 2), round(float(arguments[3]), 2)) else: self.otherPlayer.hide() except Exception as error: Logger.error(error)
def printThreads(self): while True: Logger.log(f'Current number of threads: {active_count()}') if active_count() > 30: if not self.threadBypass: threadLimit = Error( text= 'Thread count exceeded 30 threads [warning level] - to carry on running the program and ignore any other warnings, click \'Ignore\', to close the program, click \'Exit\'. The program ' 'will force close at 80 threads', options=['Ignore', 'Exit']) threadLimit.show() if threadLimit.outcome() == 'Ignore': self.threadBypass = True elif threadLimit.outcome() == 'Exit': self.GameWindow.destroy() exit(69) if active_count() > 80: Logger.log('Force shutdown - exceeded 80 threads.', 'ERROR') self.GameWindow.destroy() sleep(5)
def __init__(self): # self.EXTERNAL_IP = get('https://api.ipify.org').text self.EXTERNAL_IP = '12.345.67.890' self.IP = '0.0.0.0' self.PORT = 6969 self.BUFFER_SIZE = 35 self.LISTEN_INT = 10 self.LIST = [] self.MIN_VERSION = 0.00 self.SERVER_VERSION = 1.00 self.SERVER_NAME = 'Default Server' self.LAUNCH_TIME = datetime.now().strftime('%H:%M:%S') self.connectedUsers = {} self.extendedUsers = {} self.reversedUsers = {} self.serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.serverSocket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) self.serverStatus = True self.serverConfig = configparser.ConfigParser() self.serverConfig.read('server-config.ini') """ self.SERVER_NAME = self.serverConfig['Server']['Name'] self.SERVER_VERSION = float(self.serverConfig['Server']['Server Version']) self.MIN_VERSION = float(self.serverConfig['Server']['Minimum Version']) self.ALLOW_DUPLICATES = self.serverConfig['Server']['Duplicate Names'] """ self.serverInformation = { 'Server Information': { 'Server Name': self.SERVER_NAME, 'Uptime': self.LAUNCH_TIME, 'Minimum Version': self.MIN_VERSION, 'Server Version': self.SERVER_VERSION } } Logger.log(f'Initialized chat server with version {str(self.MIN_VERSION)} support.')
def lobby(self, host=True): def send(event): if self.lobbyEntry.get() != '': self.send('CHAT^{0} ({1}): '.format((testData['information']['username']).upper(), self.gameState) + self.lobbyEntry.get() + '\n') self.lobbyEntry.delete(0, END) if host: Logger.log('Created new lobby successfully.') self.chat('HOST: Created new lobby\n') self.gameState = 'HOST-LOBBY' self.gamePlayers.append(testData['information']['username']) self.refresh() else: Logger.log('Joined a lobby successfully.') self.gameState = 'JOIN-LOBBY' Logger.log(f'Set game state to \'{self.gameState}\'.') self.clear() self.lobbyChat.place(relx=.052, rely=.26) self.lobbyEntry.bind('<Return>', send) self.lobbyEntry.place(relx=.052, rely=.73) self.lobbyEntry.focus_force() self.lobbyPlayers.place(relx=.61, rely=.25) self.playerOne.place(relx=.61, rely=.35) self.playerTwo.place(relx=.61, rely=.45) self.playerThree.place(relx=.61, rely=.55) self.playerFour.place(relx=.61, rely=.65) self.readyOne.place(relx=.92, rely=.35) self.readyTwo.place(relx=.92, rely=.45) self.readyThree.place(relx=.92, rely=.55) self.readyFour.place(relx=.92, rely=.65) self.lobbyReady.place(relx=.6075, rely=.75) self.lobbyLeave.place(relx=.8, rely=.75)
def receive(self): Logger.log(f'Started listening for connections at [{self.EXTERNAL_IP}:{self.PORT}]') Logger.log(f'Accepting local connections at [127.0.0.1:{self.PORT}]') while self.serverStatus: try: read_sockets, write_sockets, error_sockets = select.select(self.LIST, [], []) for sock in read_sockets: if sock == self.serverSocket: sockfd, address = self.serverSocket.accept() self.LIST.append(sockfd) Logger.log(f'Client [{address[0]}:{address[1]}] connected to the server.', 'CONNECT') else: try: receivedData = sock.recv(self.BUFFER_SIZE, ) except: try: try: disconnected_user = self.connectedUsers[address] del self.connectedUsers[address] del self.extendedUsers[disconnected_user] except: disconnected_user = '******' Logger.log(f'Client [{address[0]}:{address[1]}] ({disconnected_user}) disconnected from the server.', 'DISCONNECT') self.broadcast(f'({disconnected_user}) left the server') self.broadcast(f'LEFT<>{disconnected_user}') except Exception as error: Logger.error(error) sock.close() self.LIST.remove(sock) continue if receivedData: arguments = receivedData.decode().split('<>') if 'DISCONNECT' in receivedData.decode(): try: disconnected_user = self.connectedUsers[address] del self.connectedUsers[address] del self.extendedUsers[disconnected_user] except: disconnected_user = '******' Logger.log(f'Client [{address[0]}:{address[1]}] ({disconnected_user}) disconnected from the server.', 'DISCONNECT') Logger.log(f'Received quit command from client [{address[0]}:{address[1]}]') self.broadcast(f'({disconnected_user}) left the server') self.broadcast(f'LEFT<>{disconnected_user}') sock.close() self.LIST.remove(sock) continue elif arguments[0] == 'USERNAME': self.connectedUsers[address] = arguments[1] self.extendedUsers[arguments[1]] = sock Logger.log(f'Allowed connection from [{address[0]}:{address[1]}] ({arguments[1]})', 'CONNECT') elif arguments[0] == 'CONNECT4': self.handle_game_commands(arguments, sock, self.connectedUsers[address]) elif arguments[0] == 'ONLINE': userList = '' for user in self.connectedUsers: userList = userList + self.connectedUsers[user] + ';' sock.send(str.encode('USER_LIST<>' + userList)) Logger.log(f'[{address[0]}:{address[1]}] ({self.connectedUsers[address]}) requested user list.') Logger.log(f'Current connected users: {userList.replace(";", " ")}') elif arguments[0] == 'CLIENT_INFORMATION': Logger.log(f'Received client information from [{address[0]}:{address[1]}]') clientInformation = ast.literal_eval(arguments[1]) clientData = [] for field in ['Username', 'Version', 'Rank']: clientData.append(str([clientInformation['Client Information'][field]][0])) if clientData[0] == '' or clientData[0] == ' ': sock.send(b'CONN_ERROR<>Invalid username (username not allowed)') Logger.log(f'Rejected connection from [{address[0]}:{address[1]}] due to invalid username.') sock.close() self.LIST.remove(sock) else: userListByName = [] for user in self.connectedUsers: userListByName.append(self.connectedUsers[user]) if clientData[0] in userListByName: sock.send(b'CONN_ERROR<>A user with that name is already connected (use a different username)') Logger.log(f'Rejected connection from [{address[0]}:{address[1]}] ({clientData[0]}) due to duplicate username.', 'DISCONNECT') sock.close() self.LIST.remove(sock) else: if float(clientData[1]) < self.MIN_VERSION: sock.send(str.encode(f'CONN_ERROR<>Client is out of date (latest version is {str(self.MIN_VERSION)})')) Logger.log(f'Rejected connection from [{address[0]}:{address[1]}] ({clientData[0]}) due to outdated client [{clientData[1]}]', 'DISCONNECT') sock.close() self.LIST.remove(sock) else: self.connectedUsers[address] = clientData[0] self.extendedUsers[clientData[0]] = sock sock.send(b'CONN_SUCCESS<>Successfully connected to the server.') Logger.log(f'Allowed connection from [{address[0]}:{address[1]}] ({clientData[0]}) [{clientData[1]}]', 'CONNECT') time.sleep(0.10) start_dt = datetime.strptime(self.serverInformation['Server Information']['Uptime'], '%H:%M:%S') end_dt = datetime.strptime(datetime.now().strftime('%H:%M:%S'), '%H:%M:%S') diff = (end_dt - start_dt) serverInformationTemp = self.serverInformation serverInformationTemp['Server Information']['Uptime'] = str(diff) time.sleep(0.10) sock.send(str.encode(f'SERVER_INFORMATION<>{str(serverInformationTemp)}')) Logger.log(f'Sent server information to client [{address[0]}:{address[1]}] ({clientData[0]})') self.serverInformation['Server Information']['Uptime'] = self.LAUNCH_TIME else: self.broadcast(receivedData.decode()) except Exception as error: Logger.error(error)
class Downloader: def __init__(self, error_messages, packager, p_tokens_file): self.__error_messages = error_messages self.__packager = packager self.__p_tokens_file = p_tokens_file self.__logger = Logger() def commander(self, command, args): ''' download (package name[0]): downloads clips from given package ''' if command == 'download': filter = self.__filter(args, 1) if filter: name = args[0] package = self.__packager.get(name) for streamer in package.get_data()['streamers']: self.__download(streamer, package) return True return False def __filter(self, args, ammount): if len(args) >= ammount: return True else: print(ConsoleColors.RED + 'Error: {0}'.format(self.__error_messages[0]) + ConsoleColors.RESET) def __check_paths(self, path): if not os.path.exists(self.__p_packages_file): os.mkdir(path) def __download(self, streamer, package): with open(self.__p_tokens_file, 'r') as f: client_id = json.load(f)['twitch']['client_id'] access_token, broad_id = Downloader.check_username(streamer).split("&") if package.get_data()['period'] == 'week': start = generate(datetime.utcnow().replace(tzinfo=pytz.utc) - timedelta(days=7)) end = generate(datetime.utcnow().replace(tzinfo=pytz.utc)) elif package.get_data()['period'] == 'month': start = generate(datetime.utcnow().replace(tzinfo=pytz.utc) - timedelta(days=30)) end = generate(datetime.utcnow().replace(tzinfo=pytz.utc)) count = 0 pagination = '' times = list() game_ids = dict() while count < int(package.get_data()['limit']): r = requests.get( 'https://api.twitch.tv/helix/clips?broadcaster_id={}&first={}&started_at={}&ended_at={}&after={}' .format(broad_id, package.get_data()['limit'], start, end, pagination), headers={ 'Authorization': 'Bearer ' + access_token, 'Client-ID': client_id }) clips = r.json()['data'] if len(clips) > 0: for clip in clips: if type(clip) == dict: if clip['game_id'] not in game_ids: game_ids[clip['game_id']] = 1 else: game_ids[clip['game_id']] += 1 thumbnail_url = clip['thumbnail_url'] mp4_url = thumbnail_url.split('-preview', 1)[0] + '.mp4' number = count + 1 if len(str(number)) == 1: number = '0' + str(number) mp4_name = str( Path(package.get_data()['clips_folder']) / str(str(number) + '.mp4')) self.__logger.log("Downloading: " + str(mp4_name)) res = requests.get(mp4_url) with open(mp4_name, 'wb') as f: f.write(res.content) cmd = 'ffprobe -show_entries format=duration -v quiet -of csv="p=0" ' + mp4_name duration = float(os.popen(cmd).read()) created_at = datetime.strptime(clip['created_at'], '%Y-%m-%dT%H:%M:%SZ') ended_at = created_at + timedelta(0, duration) exist = False if len(times) > 0: for i in range(len(times)): if times[i]['created_at'] < created_at < times[ i]['ended_at'] or times[i][ 'created_at'] < ended_at < times[ i]['ended_at']: exist = True break else: time_meta = { 'created_at': created_at, 'ended_at': ended_at } times.append(time_meta) else: time_meta = { 'created_at': created_at, 'ended_at': ended_at } times.append(time_meta) if exist: os.remove(mp4_name) else: count += 1 if count >= int(package.get_data()['limit']): break pagination = r.json()['pagination']['cursor'] else: raise Exception('Clips not found') games_sorted = sorted(game_ids.items(), key=lambda x: x[1], reverse=True) stop = 1 if len(games_sorted) > 1: stop = 2 games = list() for i in range(stop): r = requests.get('https://api.twitch.tv/helix/games?id=' + games_sorted[i][0], headers={ 'Authorization': 'Bearer ' + access_token, 'Client-ID': client_id }) games.append(r.json()['data'][0]['name']) package.get_data()['additional_info']['games'] = games package.update() self.__logger.separator() @staticmethod def check_username(username): with open(Path('tokens/tokens.json'), 'r') as f: credentials = json.load(f)['twitch'] try: r = requests.post( 'https://id.twitch.tv/oauth2/token?client_id={0}&client_secret={1}&grant_type=client_credentials' .format(credentials['client_id'], credentials['client_secret'])) access_token = r.json()['access_token'] r = requests.get('https://api.twitch.tv/helix/users?login='******'Authorization': 'Bearer ' + access_token, 'Client-ID': credentials['client_id'] }) broad_id = r.json()['data'][0]['id'] if not broad_id: print('Bad request, check username or user banned') return False except: print('Failed to connect to Twitch API') return False return access_token + '&' + broad_id
class Encoder: __DEFAULT = { 'FPS': '60/1', 'WIDTH': '1920', 'HEIGHT': '1080', 'TBN': '1/15360', 'HZ': '1/44100' } def __init__(self, error_messages, packager): self.__error_messages = error_messages self.__packager = packager self.__logger = Logger() def commander(self, command, args): ''' encode (package name[0]): encodes clips to make all clips has the same parameters options ''' if command == 'encode': filter = self.__filter(args, 1) if filter: name = args[0] package = self.__packager.get(name) if not package: return True folder = package.get_data()['clips_folder'] for subdir, dirs, files in os.walk(folder): files.sort() for file in files: mp4_file = Path(folder) / file opt = self.__check_video(mp4_file) if opt == '': continue else: self.__logger.log('Re-encoding video {}'.format(mp4_file)) cmd = 'ffmpeg -i ' + str(mp4_file) + opt + str(mp4_file).replace('.mp4', '') + 'converted.mp4' r = subprocess.run(cmd, capture_output=True, shell=True) os.remove(mp4_file) self.__logger.separator() return True else: return False def __filter(self, args, ammount): if len(args) >= ammount: return True else: print(ConsoleColors.RED + 'Error: {0}'.format(self.__error_messages[0]) + ConsoleColors.RESET) def __check_video(self, video): cmd = 'ffprobe -v error -of json -show_entries stream=time_base,r_frame_rate,width,height ' + str(video) r = os.popen(cmd).read() j_streams = json.loads(r)['streams'] streams = list([{}, {}]) for j_stream in j_streams: if 'width' in j_stream.keys(): streams[0] = j_stream else: streams[1] = j_stream opt = '' if str(streams[0]['width']) != self.__DEFAULT['WIDTH']: opt = opt + ' -vf scale=' + self.__DEFAULT['WIDTH'] + ':' + self.__DEFAULT['HEIGHT'] opt = opt + ' -video_track_timescale ' + self.__DEFAULT['TBN'][2:] opt = opt + ' -r ' + self.__DEFAULT['FPS'][:-2] else: if streams[0]['time_base'] != self.__DEFAULT['TBN']: opt = opt + ' -video_track_timescale ' + self.__DEFAULT['TBN'][2:] if streams[0]['r_frame_rate'] != self.__DEFAULT['FPS']: opt = opt + ' -r ' + self.__DEFAULT['FPS'][:-2] if streams[1]['time_base'] != self.__DEFAULT['HZ']: opt = opt + ' -ar ' + self.__DEFAULT['HZ'][2:] if opt != '': opt = opt + ' ' return opt
def startListening(self): # _thread.start_new_thread(self.makeItems, ()) try: self.clientSocket.connect((self.IP, self.PORT)) self.hasConnected = True self.clientSocket.send(str.encode(f'USERNAME<>{Username}')) Logger.log('Connected to server correctly.') # self.clientSocket.send(str.encode('CLIENT_INFORMATION<>' + str(clientInformation))) except Exception as e: self.notificationText.set('Could not connect to the local server.') self.Window.after(3000, lambda: self.notificationText.set('')) Logger.error(e) Logger.log('Failed to connect to the local game server.', 'ERROR') if self.hasConnected: while True: try: receive_data = self.clientSocket.recv(35) # print(receive_data.decode()) arguments = receive_data.decode().split('<>') if arguments[0] == 'CONN_ERROR': Logger.log( 'Server rejected connection based on client information.', 'DISCONNECT') Logger.log(arguments[1]) break elif arguments[0] == 'CONN_SUCCESS': Logger.log(arguments[1]) elif arguments[0] == 'SERVER_INFORMATION': serverInfo = ast.literal_eval(str(arguments[1])) serverData = [] for field in [ 'Server Name', 'Uptime', 'Minimum Version', 'Server Version' ]: serverData.append( serverInfo['Server Information'][field]) Logger.log( f'{field}: {str(serverInfo["Server Information"][field])}', 'SERVER') elif arguments[0] == 'ITEM': # print(receive_data.decode()) posArgs2 = receive_data.decode().strip('ITEM<>') posArgs2 = posArgs2.split(',') self.createItem(float(posArgs2[0]), float(posArgs2[1])) elif arguments[0] == 'USER_LIST': all_users = arguments[1].split(';') for user in all_users: if user is not '': Logger.log(user, 'USER LIST') elif arguments[0] == 'BALL': posArgs3 = receive_data.decode().strip('BALL<>') posArgs3 = posArgs3.split(',') self.drawBullet(posArgs3[0], posArgs3[1], posArgs3[2], posArgs3[3], posArgs3[4]) elif arguments[0] == 'POSITION': # print(receive_data.decode()) userName = arguments[1] if userName != Username: posArgs = receive_data.decode().strip( 'POSITION<>' + userName) posArgs = posArgs.split(',') self.setOLoc(posArgs[0], posArgs[1], userName) except Exception as e: self.notificationText.set( 'Lost connection to the game server.') self.Window.after(3000, lambda: self.notificationText.set('')) Logger.error(e) Logger.log( 'Lost connection to the game server or received invalid data.', 'ERROR') break
def __init__(self, uName): self.WINDOW_BACKGROUND = '#141414' self.WINDOW_FOREGROUND = '#FFFFFF' self.WINDOW_RESOLUTION = '600x350' self.WINDOW_TITLE = 'Placeholder' self.IP = '127.0.0.1' self.PORT = 6666 def createBullet(event): bulletVelocity = [ self.getVelocityX(Username) * 2, self.getVelocityY(Username) * 2 ] self.clientSocket.send( str.encode( f'BALL<>{self.locations[self.locIndex][0]:.2f},{self.locations[self.locIndex][1]:.2f},{bulletVelocity[0]},{bulletVelocity[1]},{self.playerColours[self.locIndex]}' )) def handleMovementR(event): self.setVelocityX(Username, 0.01) self.setVelocityY(Username, 0.00) self.strVolX = '+0.01' def handleMovementL(event): self.setVelocityX(Username, -0.01) self.setVelocityY(Username, 0.00) self.strVolX = '-0.01' def handleMovementU(event): self.setVelocityY(Username, -0.01) self.setVelocityX(Username, 0.00) self.strVolY = '-0.01' def handleMovementD(event): self.setVelocityY(Username, 0.01) self.setVelocityX(Username, 0.00) self.strVolY = '+0.01' def handleMovementS(event): self.setVelocityY(Username, 0.00) self.setVelocityX(Username, 0.00) def handlePosW(event): if self.facing != 1: if self.facing == 4: self.locations[self.locIndex][0] = self.locations[ self.locIndex][0] + 0.028 self.facing = 1 self.locations[self.locIndex][1] = self.locations[ self.locIndex][1] - 0.0625 self.GAME_PIECE_PLAYER_2.config(text="""↑ ●""") def handlePosS(event): pass # """ # if self.facing != 3: # self.facing = 1 # self.locations[self.locIndex][1] = self.locations[self.locIndex][1] + 0.0625 # self.GAME_PIECE_PLAYER_2.config(text="""● #↓""") def handlePosA(event): if self.facing != 4: if self.facing == 1: self.locations[self.locIndex][1] = self.locations[ self.locIndex][1] + 0.0625 self.locations[self.locIndex][0] = self.locations[ self.locIndex][0] - 0.028 self.facing = 4 self.GAME_PIECE_PLAYER_2.config(text="← ●") def handlePosD(event): if self.facing != 2: if self.facing == 1: self.locations[self.locIndex][1] = self.locations[ self.locIndex][1] + 0.0625 elif self.facing == 4: self.locations[self.locIndex][0] = self.locations[ self.locIndex][0] + 0.028 self.facing = 2 self.GAME_PIECE_PLAYER_2.config(text="● →") self.gamePlayers = ['Shivam', 'TEST', 'TEST2', 'TEST3'] self.velocityX = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] self.velocityY = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0] self.hasConnected = False self.clientSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) self.clientSocket.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1) self.locations = [[0.05, 0.25], [0.05, 0.45], [0.05, 0.65], [0.05, 0.85]] self.playerColours = ['#e74c3c', '#16a085', '#3498db', '#f39c12'] self.Window = Tk() self.Window.geometry(self.WINDOW_RESOLUTION) self.Window.configure(bg=self.WINDOW_BACKGROUND) self.Window.title(self.WINDOW_TITLE) self.locIndex = self.gamePlayers.index(uName) self.facing = 3 self.tickrate = 40 self.strVolX = '+0.00' self.strVolY = '-0.00' self.currentPosition = StringVar() self.currentPosition.set( f'X: {self.getVelocityX(Username)} ● Y: {self.getVelocityY(Username)} | {self.locations[self.locIndex][0]:.2f}, {self.locations[self.locIndex][1]:.2f} [TR: {self.tickrate}] [User: {Username}]' ) self.notificationText = StringVar() self.notificationText.set(f'{uName} joined the game.') self.Window.bind('<Right>', handleMovementR) self.Window.bind('<Left>', handleMovementL) self.Window.bind('<Up>', handleMovementU) self.Window.bind('<Down>', handleMovementD) self.Window.bind('<space>', handleMovementS) self.Window.bind('z', createBullet) self.Window.bind('Z', createBullet) self.bullet = None ''' self.Window.bind('w', handlePosW) self.Window.bind('W', handlePosW) self.Window.bind('s', handlePosS) self.Window.bind('S', handlePosS) self.Window.bind('a', handlePosA) self.Window.bind('A', handlePosA) self.Window.bind('d', handlePosD) self.Window.bind('D', handlePosD) ''' self.GAME_PIECE_PLAYER_1 = Label(self.Window, text='●', bg=self.WINDOW_BACKGROUND, fg='#e74c3c', font=('Segoe UI', 12, 'bold')) self.GAME_PIECE_PLAYER_1.place(relx=.05, rely=.25) self.GAME_PIECE_PLAYER_2 = Label(self.Window, text="●", bg=self.WINDOW_BACKGROUND, fg='#16a085', font=('Segoe UI', 12, 'bold')) self.GAME_PIECE_PLAYER_2.place(relx=.05, rely=.45) self.GAME_PIECE_PLAYER_3 = Label(self.Window, text='●', bg=self.WINDOW_BACKGROUND, fg='#3498db', font=('Segoe UI', 12, 'bold')) self.GAME_PIECE_PLAYER_3.place(relx=.05, rely=.65) self.GAME_PIECE_PLAYER_4 = Label(self.Window, text='●', bg=self.WINDOW_BACKGROUND, fg='#f39c12', font=('Segoe UI', 12, 'bold')) self.GAME_PIECE_PLAYER_4.place(relx=.05, rely=.85) self.currentVelocityX = Label(self.Window, textvariable=self.currentPosition, bg=self.WINDOW_BACKGROUND, fg=self.WINDOW_FOREGROUND, font=('Courier New', 12, 'bold')) self.currentVelocityX.place(relx=.025, rely=.02) self.notification = Label(self.Window, textvariable=self.notificationText, bg=self.WINDOW_BACKGROUND, fg='#e74c3c', font=('Courier New', 12, 'bold')) self.notification.place(relx=.025, rely=.90) self.gamePieces = [ self.GAME_PIECE_PLAYER_1, self.GAME_PIECE_PLAYER_2, self.GAME_PIECE_PLAYER_3, self.GAME_PIECE_PLAYER_4 ] self.Window.after(3000, lambda: self.notificationText.set('')) self.currentItemCoords = [0, 0] Logger.log( f"Launched game window - running on {self.tickrate} tickrate.") # _thread.start_new_thread(self.updatePieces, ()) _thread.start_new_thread(self.startListening, ()) _thread.start_new_thread(self.updatePieces, ()) # _thread.start_new_thread(self.collisionDetection, ()) # _thread.start_new_thread(self.makeItems, ()) _thread.start_new_thread(self.Window.mainloop(), )
class Editor: def __init__(self, error_messages, packager, p_videos_media): self.__error_messages = error_messages self.__packager = packager self.__p_videos_media = p_videos_media self.__logger = Logger() def commander(self, command, args): ''' edit (package name[0]): concatenates all clips + outro, then inserts video intro at the beginning ''' if command == 'edit': filter = self.__filter(args, 1) if filter: name = args[0] package = self.__packager.get(name) if not package: return True p_clips = package.get_data()['clips_folder'] p_output = package.get_data()['output_folder'] concat_output = Path(p_output) / 'concat.txt' if os.path.exists(concat_output): os.remove(concat_output) with open(concat_output, 'x') as f: for subdir, dirs, files in os.walk(p_clips): files.sort() for file in files: mp4_file = Path(p_clips) / file f.write('file ' + str(mp4_file) + '\n') f.write('file ' + str(self.__p_videos_media / 'outro.mp4')) date = datetime.now() output_video = Path(p_output) / str(name + date.strftime('%Y-%m-%d') + '.mp4') self.__generate_video(package, concat_output, output_video) self.__logger.log('video {} created'.format(output_video)) self.__logger.separator() return True else: return False def __filter(self, args, ammount): if len(args) >= ammount: return True else: print(ConsoleColors.RED + 'Error: {0}'.format(self.__error_messages[0]) + ConsoleColors.RESET) def __generate_video(self, p, of, ov): cmd = 'ffmpeg -f concat -safe 0 -i {} -c copy {}'.format(of, ov) r = subprocess.run(cmd, shell=True, capture_output=True) intro = Path(self.__p_videos_media) / 'intro.mov' final_ov = str(ov).replace('mp4', '') + 'final.mp4' cmd = 'ffmpeg -i {} -i {} -filter_complex "[1:v]setpts=PTS-0/TB[a]; [0:v][a]overlay=enable=gte(t\,0):eof_action=pass[out]; [0][1]amix[a]" -map [out] -map [a] -c:v libx264 -crf 18 -pix_fmt yuv420p {}'.format(ov, intro, final_ov) r = subprocess.run(cmd, shell=True, capture_output=True) p.get_data()['additional_info']['output_video'] = str(final_ov) p.update() ''' create twitter_video ''' twitter_video = 'test.mp4' p.get_data()['additional_info']['twitter_video'] = twitter_video p.update()
def update(steps: int = 1): status, json_response = update(steps=steps) Logger.log(f"{status:d}\n{json_response:s}")
def plot(iteration: int, batch: Sequence[Tuple[str, str, Sequence[float]]]): status, json_response = send_data(iteration, batch) Logger.log(f"{status:d}\n{json_response:s}")
class Card: __hash = None __url = None __title = None __price = None __imageUrl = None __logger = None __store = None def __init__(self, url: str, title: Union[str, None] = None, price: Union[str, None] = None, imageUrl: Union[str, None] = None) -> bool: self.__logger = Logger() self.__telegram = Telegram() try: self.__store = Store() except SQLiteError as error: self.__logger.logError(error) raise Exeption('Can Not Init Store') self.__url = url self.__logger.log('Card URL: %s' % url) self.__hash = hashlib.md5(self.__url.encode('utf-8')).hexdigest() self.__logger.log('Card Hash: %s' % self.__hash) title = self.__formatTitle(title) if title is not None: self.__title = title self.__logger.log('Card Title: %s' % title) price = self.__formatPrice(price) if price > 0: self.__price = price self.__logger.log('Card Price: %i' % price) if imageUrl is not None: self.__imageUrl = imageUrl self.__logger.log('Card Image URL: %s' % imageUrl) def isCardExists(self) -> bool: try: row = self.__store.getRowByHash(self.__hash) if row is not None: return True except SQLiteError as error: self.__logger.logError(error) return False def save(self) -> bool: if not self.__isValidFormatUrl(): self.__logger.logError('Card URL %s Has Bad Format' % self.__url) return False if (self.isCardExists()): self.__logger.log('Card Already Exists') return False try: return self.__store.insertRow(self.__hash, self.__url, self.__title, self.__price, self.__imageUrl) except SQLiteError as error: self.__logger.logError(error) return False def send(self): message = self.__url if self.__price is not None: message = 'Price %s $\n%s' % (f'{self.__price:,}'.replace( ',', ' '), message) if self.__title is not None: message = '%s\n%s' % (self.__title.upper(), message) self.__telegram.sendToChannel(message) self.__logger.log('Card Sent To Channel') def __isValidFormatUrl(self) -> bool: pattern = re.compile('^http.*?$') return pattern.match(self.__url) is not None def __formatPrice(self, price: Union[str, None]) -> int: if price is None: return 0 return int(price.replace(' ', '')) def __formatTitle(self, title: Union[str, None]) -> Union[str, None]: if title is None: return None return title.replace('<sup>2</sup>', '²')