class Server(object): def __init__(self, host=None, port=None, max_clients=None): if not host: host = os.getenv('HOST', '0.0.0.0') if not port: port = os.getenv('PORT', 31337) if not max_clients: max_clients = os.getenv('MAX_CLIENTS', 15) self._pool = Pool(int(max_clients)) self._server = StreamServer((host, int(port)), self.connection_handler, spawn=self._pool) self._protocol = DataHandler() self._kv = ExpiringDict() self._commands = self.get_commands() def get_commands(self): return { 'GET': self.get, 'SET': self.set, 'DEL': self.delete, 'KEYS': self.keys, 'FLUSHDB': self.flush, 'EXPIRE': self.expire, 'HGET': self.hget, 'HSET': self.hset, 'LSET': self.lset, 'RPUSH': self.rpush, 'LPUSH': self.lpush, 'LRANGE': self.lrange, 'LINDEX': self.lindex } def connection_handler(self, conn, address): logger.info('Connection received: %s:%s' % address) socket_file = conn.makefile('rwb') while True: try: data = self._protocol.handle_request(socket_file) except Disconnect: logger.info('Client went away: %s:%s' % address) break try: resp = self.get_response(data) except CommandError as exc: logger.exception('Command error') resp = Error(exc.args[0]) self._protocol.write_response(socket_file, resp) def run(self): self._server.serve_forever() def get_response(self, data): if not isinstance(data, list): try: data = data.split() except: raise CommandError('Request must be list or simple string.') if not data: raise CommandError('Missing command') command = data[0].upper() if command not in self._commands: raise CommandError('Unrecognized command: %s' % command) else: logger.debug('Received %s', command) try: response = self._commands[command](*data[1:]) except TypeError: raise CommandError( f'ERR wrong number of arguments for {command.lower()} command') return response def get(self, key): return self._kv.get(key) def set(self, key, value): self._kv[key] = value return '1' def delete(self, key): if key in self._kv: del self._kv[key] return 1 return 0 def keys(self, pattern): r = [] if pattern == '*': pattern = '\w*' for k in self._kv.keys(): if re.match(pattern, k): r.append(k) return r def flush(self): kvlen = len(self._kv) self._kv.clear() return str(kvlen) def expire(self, key, ttl): value = self._kv.get(key, None) if value: del self._kv[key] self._kv.ttl(key, value, float(ttl)) return 1 return 0 def hset(self, key, field, value): self._kv.setdefault(key, {}) self._kv[key][field] = value return 1 def hget(self, k, field): if self._kv.get(k): return self._kv[k].get(field) def lset(self, key, index, value): self._kv.setdefault(key, []) self._kv[key][int(index)] = value return 'OK' def rpush(self, key, *value): self._kv.setdefault(key, []) for v in value: self._kv[key].append(v) return len(self._kv[key]) def lpush(self, key, *value): self._kv.setdefault(key, []) for v in value: self._kv[key].insert(0, v) return len(self._kv[key]) def lrange(self, key, start, end): if isinstance(self._kv.get(key), list): if end == '-1': return self._kv[key][int(start):] return self._kv[key][int(start):int(end) + 1] return None def lindex(self, key, index): if isinstance(self._kv.get(key), list): try: return self._kv[key][int(index)] except IndexError: return None return None
def get_info(): global corona_dict corona_dict['world'] = covid19.getLatest() corona_dict['ru'] = covid19.getLocationByCountryCode("RU")[0]['latest'] for event in longpoll.listen(): if event.type == VkBotEventType.MESSAGE_NEW: text = event.object.text log.info(f'message {text} id {event.obj.peer_id}') if text == 'Начать': message = 'Начали' elif text == 'Коронавирус в мире': if not corona_dict.get('world'): get_info() message = f'🤧 Заражено: {corona_dict["world"]["confirmed"]} человек\n\ 😲 Умерло: {corona_dict["world"]["deaths"]} человек\n\ 😎 Излечено: {corona_dict["world"]["recovered"]} человек' elif text == 'Коронавирус в россии': if not corona_dict.get('ru'): get_info() message = f'🤧 Заражено: {corona_dict["ru"]["confirmed"]} человек\n\ 😲 Умерло: {corona_dict["ru"]["deaths"]} человек\n\ 😎 Излечено: {corona_dict["ru"]["recovered"]} человек' else: message = 'я не знаю такой команды' vk.messages.send(peer_id=event.obj.peer_id,