def authorize(self, email): """ Establece el buzón receptor dado como autorizado. :param email: Identificador del buzón. :return: El buzón autorizado. """ from pending_authorization import PendingAuthorizationManager from core.logger import Logger try: entity = self.get_by_email(email) if entity is not None: # Marcamos el buzón como autorizado. entity.is_authorized = True # Añadimos la información de tracking. entity.updated_by = self._user entity.put() # Eliminamos la autorización. PendingAuthorizationManager.delete(entity.email) except Exception as e: Logger.error(e) raise e return entity.to_dict()
def wrapper(request_handler, *args, **kwargs): # Almacenamos la URL de origen. self._origin = request_handler.request.path # Obtenemos las credenciales del usuario en sesión a partir de su almacén. storage = self.get_storage_for_user_in_request(request_handler) credentials = storage.get() Logger.info("Credentials...{}".format(credentials)) Logger.info("Origin......{}".format(self._origin)) # Si no existen credenciales de usuario almacenadas o bien están caducadas. if credentials is None or credentials.access_token_expired: # Creamos un flujo OAuth. self.create_flow(request_handler) # Obtenemos la URL de autorización. authorize_url = self._flow.step1_get_authorize_url() # Llevamos al usuario a la pantalla de autorización. output = request_handler.redirect(authorize_url) # En caso contrario, ejecutamos el método decorado. else: output = method(request_handler, *args, **kwargs) return output
def find_messages(cls, email): """ Obtiene la lista de mensajes recibidos en el buzón. :param email: Buzón de correo. :return: La lista de mensajes. """ from clients.gmail_api import GmailApiClient from core.logger import Logger try: messages = [] resource = GmailApiClient(email).messages() page_token = None while True: response = resource.list( pageToken=page_token, includeSpamTrash=False, q="in:inbox is:unread" ) if "messages" in response: for message in response["messages"]: if not any(x for x in messages if x["id"] == message["id"]): messages.append(message) if "nextPageToken" in response: page_token = response["nextPageToken"] else: break except Exception as e: Logger.error(e) raise e return messages
def parse_criteria(cls, criteria): result = '' for key in criteria: if type(criteria[key]) == dict: if key.upper() == 'NOT': result += ' NOT (%s) ' % cls.parse_criteria(criteria[key]) elif key.upper() in ['AND', 'OR']: result += ' (' #parse each value in criteria[key] and stick key in between them innerResults = [] for innerKey in criteria[key]: innerResults.append(cls.parse_criteria({innerKey: criteria[key][innerKey]})) result += key.upper().join(innerResults) result += ') ' else: Logger.get_logger(__name__).warn('I\'m sorry, I don\'t speak idiot. Couldn\'t parse operator declaration: %s', key) else: if type(criteria[key]) == str: result += ' %s = "%s" ' % (key, criteria[key]) else: result += ' %s = %s ' % (key, criteria[key]) if result == '': result = '1' return result
def authorize(self, email): """ Establece el buzón receptor dado como autorizado, crea las etiquetas DUPLICADO, GESTIONADO, PDTE REINTENTAR y ERROR en el buzón dado. :param email: Identificador del buzón. :return: El buzón autorizado. """ from pending_authorization import PendingAuthorizationManager from core.logger import Logger try: entity = self.get_by_email(email) if entity is not None: # Marcamos el buzón como autorizado. entity.is_authorized = True # Añadimos la información de tracking. entity.updated_by = self._user entity.put() # Obtenemos el diccionario que representa el buzón actualizado. entity = entity.to_dict() # Eliminamos la autorización. PendingAuthorizationManager.delete(entity["user_id"]) except Exception as e: Logger.error(e) raise e return entity
def _post_message(self, message): """ Send the given message to the Facebook Messenger platform. :param message: The message to post. :return: The Facebook Messenger response. """ from core.logger import Logger from google.appengine.api import urlfetch from json import dumps try: # Post the message to the Facebook Messenger platform. r = urlfetch.fetch( url=self._fb_messenger_api_url, method=urlfetch.POST, headers={"Content-Type": "application/json"}, payload=dumps(message) ) # Parse the response. response = r.content if r.status_code == 200 else None Logger.info("Facebook response:\n%s" % response) # In case of error. except BaseException as e: Logger.error(e) response = None # Return the parsed response. return response
def create(email, group_id, mailbox_id): """ Crea la autorización pendiente para el buzón dado. :param email: Usuario del buzón. :param group_id: Identificador del grupo. :param mailbox_id: Identificador del buzón. :return: La autorización creada. """ from core.logger import Logger try: # Creamos la entidad. entity = PendingAuthorizationDao( id=str(email), group_id=int(group_id), mailbox_id=int(mailbox_id) ) entity.put() # Obtenemos el diccionario que representa la autorización creada. entity = entity.to_dict() except Exception as e: Logger.error(e) raise e return entity
def authorize(self, email): """ Autoriza el buzón de correo indicado. :param email: Identificador de buzón de correo. :return: El buzón de correo autorizado. """ from managers.pending_authorization import PendingAuthorizationManager from core.logger import Logger try: entity = self.get_by_email(email) if entity is not None: Logger.info("It's authorized: {}".format(entity.is_authorized)) # Marcamos el buzón como autorizado. entity.is_authorized = True entity.updated_by = self._user entity.put() # Obtenemos el diccionario que representa el buzón actualizado. entity = entity.to_dict() # Eliminamos la autorización. PendingAuthorizationManager.delete(entity["user_id"]) except Exception as e: Logger.error(e) raise e return entity
def apply_rule(self, rule, field, message_id, label_id, resource): """ Busca una regla a aplicar en el subject del mensaje. :param rule: Regla a aplicar. :param field: Campo a aplicar la regla. :param message_id: Identificador del mensaje. :param label_id: Identificador de la label. :param resource: Recurso Gmail API. """ from re import MULTILINE, IGNORECASE, search from core.logger import Logger matches = search(rule, field, MULTILINE | IGNORECASE) if matches: Logger.info("Labeling message: {}".format(message_id)) # Modificamos el mensaje. resource.modify( id=message_id, body={ "addLabelIds": [label_id], # Añadimos la etiqueta indicada. "removeLabelIds": ["INBOX"] # Quitamos el mensaje del inbox. } ) return True return False
def get(self): from core.logger import Logger # Almacenamos las credenciales de usuario contenidas en la petición. myself.store_credentials(self) Logger.info("Origin...{}".format(myself.get_origin())) # Navegamos a la URL de origen. self.redirect("/" if myself is None or myself.get_origin() is None else myself.get_origin())
def activateLogDir(self): """ create the log directory and create the versions.xml file The log dir should be avtivate only if this object is tested as a valid toad subjects See Valifation.isAToadSubject() """ if not os.path.exists(self.__logDir): self.info("creating log dir {}".format(self.__logDir)) os.mkdir(self.__logDir) Logger.__init__(self, self.__logDir)
def setup(self): Logger.log_debug("Cockroach AI") self.item.get_tank().subscribe(self.item.get_settings().getint('events', 'lights_on'), "light_detected", self) self.item.get_tank().subscribe(self.item.get_settings().getint('events', 'lights_off'), "safe", self) self.LIGHT_TOLERANCE = self.item.get_settings().getint('cockroach', 'light_tolerance') self.LIGHT_COMMENTS = self.item.get_settings().get('cockroach', 'thoughts_light').split('||') self.COLLISION_INERCE = self.item.get_settings().getint('cockroach', 'direction_lock_duration') self.THOUGHTS_LIGHT = self.item.get_settings().get('cockroach', 'thoughts_light').split('||') self.item.get_tank().subscribe(pygame.KEYDOWN, "key_down", self) self.direction_lock = 0 random.seed()
def get_raw_message(self): """ Obtiene el bruto del mensaje correspondiente a los datos almacenados en la instancia actual. :return: Una cadena de texto con el bruto del mensaje. """ try: message = self.__create_message().as_string() raw = base64.urlsafe_b64encode(message) except Exception as e: Logger.error(e) raise e return raw
def __init__(self, message, originalException=None): """ A generic system exception @type message: str @param message: The exception message @type originalException: Exception @param originalException: The original exception raised """ logger = Logger(level=logging.ERROR) if originalException is not None: message += "\nOriginal exception:\n\t" + originalException.message Exception.__init__(self, message) logger.log(message)
def get(self): """ Obtiene los mensajes del buzón correspondiente al día recién cerrado. """ from google.appengine.api import taskqueue from managers.sender_account import SenderAccountManager from managers.recipient_account import RecipientAccountManager from managers.group import GroupManager from core.logger import Logger from json import dumps # Obtenemos las cuentas emisoras activas y autorizadas. senders = filter(lambda x: x["is_active"] and x["is_authorized"], SenderAccountManager.list()) # Obtenemos las cuentas receptoras activas y autorizadas. recipients = filter(lambda x: x["is_active"] and x["is_authorized"], RecipientAccountManager.list()) # Obtenemos los grupos activos. active_groups = filter(lambda x: x["is_active"], GroupManager.list()) # Por cada cuenta emisora en las cuentas emisoras activas y autorizadas. for sender in senders: Logger.info("Sender for...{}".format(sender)) groups = [] # Por cada grupo a los cuales pertenecen las cuenta emisora. for group in sender["groups"]: # Si encontramos algún grupo activo de los cuales pertenece la cuenta emisora, lo almacenamos. if any([k for k in active_groups if k["id"] == group["id"]]): groups.append(group) # Si hemos encontrado algún grupo activo al cual pertenezca la cuenta emisora. if groups: sender_recipients = [] # Por cada cuenta receptora en las cuentas receptoras activas y autorizadas. for recipient in recipients: # Si encontramos algúna grupo entre los cuales pertenece la cuenta receptora, que esté activo # y a la vez en la cuenta emisora, lo almacenamos. if filter(lambda x: x in recipient["groups"], groups): sender_recipients.append(recipient) Logger.info("sender-recipient...{}".format(sender_recipients)) # Creamos la task. taskqueue.add( queue_name="message-management", url="/tasks/message/management", method="POST", params={ "recipient_accounts": dumps(sender_recipients), "sender_account": dumps(sender) } )
def delete(email): """ Elimina la autorización pendiente correspondiente al buzón dado. :param email: Usuario del buzón. """ from core.logger import Logger try: entity = Key(PendingAuthorizationDao, str(email)).get() if entity is not None: entity.key.delete() except Exception as e: Logger.error(e) raise e
def __init__(self, user): """ Constructor de la clase. :param user: Usuario cuyas credenciales se usarán para conectar con Gmail API. :type user: str. """ from core.logger import Logger Logger.info("Initializing gmail client...") # Obtenemos las credenciales para el usuario dado. credentials = StorageByKeyName(CredentialsModel, user, "credentials").get() # Securizamos el cliente HTTP con ellas. http = credentials.authorize(httplib2.Http()) # Construimos el acceso a los recursos de Gmail API. self.resource = build("gmail", "v1", http=http) Logger.info("Gmail client initialized")
def __init__(self, config): """A valid individual who have the capability to run tasks. This class have the responsability to write a document of the softwares and versions into the log directory Must be validated as a prerequisite Args: config: a self.config ConfigParser object. """ self.__config = config self.__subjectDir = self.__config.get('arguments', 'subjectDir') self.__name = os.path.basename(self.__subjectDir) self.__logDir = os.path.join(self.__subjectDir, self.__config.get('dir', 'log')) #the subject logger must be call without file information during initialization Logger.__init__(self) Lock.__init__(self, self.__logDir, self.__name) Validation.__init__(self, self.__subjectDir, self.__config)
def delete_rule(self, label_id, rule_id): """ Elimina una regla de la label indicada. :param label_id: Identificador de la label. :param rule_id: Identificador de la regla. :return: El buzón actualizado. """ from core.logger import Logger entity = self.get() for idx, label in enumerate(entity.labels): if label.gmail_id == label_id: entity.labels[idx].rules = filter(lambda x: int(x.id) != int(rule_id), label.rules) Logger.info("rules...{}".format(filter(lambda x: int(x.id) != int(rule_id), label.rules))) entity.updated_by = self._user entity.put() break else: raise Exception() return entity
def update_label(self, label): """ Actualiza la label indicada. :param label: Diccionario que representa la label. :return: El buzón modificado. """ from clients.gmail_api import GmailApiClient from core.logger import Logger if "gmail_name" not in label or not label["gmail_name"]: raise Exception("The label must have a name.") if "gmail_id" not in label or not label["gmail_id"]: raise Exception("The label must have an id.") Logger.info("Gmail name...{} ... GmailID...{}".format(label["gmail_name"], label["gmail_id"])) entity = self.get() resource = GmailApiClient(entity.email).labels() for i in entity.labels: if i.gmail_id == label["gmail_id"]: updated_label = resource.update( id=i.gmail_id, body={ "name": label["gmail_name"], "labelListVisibility": "labelShow", "messageListVisibility": "show" } ) Logger.info("updated label:{}".format(updated_label)) entity.updated_by = self._user i.gmail_name = label["gmail_name"] break else: raise Exception("This label is not in this account.") entity.updated_by = self._user entity.put() return entity
def post(self): """ Obtiene los mensajes del buzón correspondiente al día recién cerrado. """ from core.logger import Logger from json import loads from clients.gmail_api import GmailApiClient try: # Obtenemos los datos de la petición. sender = loads(self.request.get("sender_account")) recipients = loads(self.request.get("recipient_accounts")) # Obtenemos los mensajes de la cuenta emisora. messages = self.find_messages(sender["email"]) resource = GmailApiClient(sender["email"]).messages() if messages: # Por cada mensaje encontrado. for message in messages: # Creamos un mensaje. mssg = GmailApiClient.Message(resource.get(id=message["id"])) # Creamos un mensaje para mappear el mensaje obtenido. mssg2 = GmailApiClient.MessageMapper() Logger.info(u"From address: {}".format(mssg.get_from())) Logger.info(u"Sender address: {}".format(mssg.get_sender())) # Seteamos los campos que nos interesan. mssg2.set_html_body(mssg.get_html_body()) mssg2.set_subject(mssg.get_from() + "$ " + mssg.get_subject()) mssg2.add_header("Return-Path", u"{}".format(mssg.get_from())) mssg2.add_header("X-Env-Sender", u"{}".format(mssg.get_from())) mssg2.from_address = u"{}".format(mssg.get_from()) Logger.info(u"New from: {}".format(mssg2.from_address)) # Agregamos los buzones receptores. for recipient in recipients: mssg2.add_recipient(recipient["email"]) sender_email = sender["email"] response = GmailApiClient(sender_email).send_message(mssg2, sender_email) # Si obtenemos respuesta, borramos los mensajes del buzón emisor. if response: GmailApiClient(sender_email).messages().delete( id=message["id"], userId=sender_email ) except Exception as e: Logger.error(e)
def post(self): """ Etiqueta los mensajes del día recién cerrado. """ from json import loads from core.logger import Logger from clients.gmail_api import GmailApiClient from managers.rules import RulesManager try: # Obtenemos los datos de la petición. recipient = loads(self.request.get("recipient_account")) messages = MessageManagementHandler.find_messages(recipient["email"]) resource = GmailApiClient(recipient["email"]).messages() for message in messages: mssg = GmailApiClient.Message(resource.get(id=message["id"])) # Por cada label existente en cada buzón receptor. for label in recipient["labels"]: # Aplicamos la regla existente por cada label. for rule in label["rules"]: rule = RulesManager(rule_id=rule["id"]).get() if self.apply_rule( rule.rule, mssg.get_plain_body() if rule.field == "body" else mssg.get_from() if rule.field == "to" else mssg.get_subject(), message["id"], label["gmail_id"], resource ): break except Exception as e: Logger.error(e)
def create_label(self, label): """ Crea una nueva etiqueta, estableciendo el buzón de correo indicado como padre. :param label: Etiqueta. :return: La etiqueta creada. """ from clients.gmail_api import GmailApiClient from core.logger import Logger from models.label import LabelDao try: # Comprobamos que los datos obligatorios vengan informados. if label.gmail_name is None: raise Exception("Label gmail_name cannot be empty.") # Establecemos el nombre de la etiqueta. gmail_name = label.gmail_name entity = self.get() # Obtenemos el acceso al recurso 'labels' de Gmail API. resource = GmailApiClient(entity.email).labels() # Obtenemos todas las etiquetas del buzón para, en caso de # existir ya, seleccionar dicha etiqueta en vez de crearla. mailbox_labels = resource.list() # Comprobamos si ya existe una etiqueta con el nombre propuesto. current_label = next((l for l in mailbox_labels["labels"] if l["name"].lower() == gmail_name.lower()), None) Logger.info("Current label: %s ", current_label) # Si no existe la creamos. if current_label is None: response = resource.create(body={ "name": gmail_name, "labelListVisibility": "labelShow", "messageListVisibility": "show" }) entity.updated_by = self._user # Añadimos el identificador obtenido. label_dao = LabelDao(**{"gmail_name": gmail_name, "gmail_id": response["id"]}) entity.labels.append(label_dao) Logger.info("Created label: {}".format(label_dao.to_dict())) else: raise Exception("This label is already in this account.") # manager.add_label(entity.gmail_id) entity.put() except Exception as e: Logger.error(e) raise e return entity
def __init__(self): # logging self.logger = Logger.get_logger(__name__) # tvrobot core object # self.tvrobot = TvRobot() # static handlers handlers = [ (r'/sms', SMSHandler), (r'/event', EventHandler), ] # tornado app settings settings = dict( debug = False, cookie_secret = config.TVROBOT['API']['cookie_secret'] ) # init app with settings and static handlers tornado.web.Application.__init__(self, handlers, **settings) self.logger.info('API initialized successfully')
def __init__(self, mod_path): """ constructor """ # logger self.logger = Logger() self.log = self.logger.log # file i/o self.file = File() # get all modules self.mod_path = mod_path self.mods = [] self.get_modules() # all loaded module self.lmod = {} # docstrings for all tools self.docstrings = {} return
def add_user(self, st): msg_dict = eval(st) user_info = self.get_file() user_id = msg_dict['user_name'] send_dict = {} if user_id not in user_info.sections() and len(user_id) != 0: user_info.add_section(msg_dict['user_name']) user_info[user_id]['state'] = '0' user_info[user_id]['password'] = msg_dict['user_password'] user_info[user_id]['home_dir'] = str(setting.Home_Dir(user_id)) os.makedirs(str(setting.Home_Dir(user_id))) # 生成个人家目录 os.makedirs(r'%s\share' % str(setting.Home_Dir(user_id))) # 生成上传文件夹 # 注册后个人存储空间为1G user_info[user_id]['memory'] = '1G' user_info[user_id]['use_space'] = '0' user_info[user_id]['balance'] = '0' user_info.write( open(r'%s\db\user_info.ini' % self.path, 'w', encoding=setting.CODING)) send_dict['user_id'] = user_id send_dict['state'] = '0' send_dict['password'] = msg_dict['user_password'] send_dict['home_dir'] = user_info[user_id]['home_dir'] send_dict['memory'] = '1G' send_dict['use_space'] = '0' send_dict['balance'] = '0' self.conn.send(str(send_dict).encode( setting.CODING)) # 用户注册信息返回给客户端 log_msg = 'account:%s operation:add_user info:registered successfully' % user_id loggers = Logger.logs('operation') loggers.info(log_msg) # 记录日志 else: self.conn.send(str(send_dict).encode(setting.CODING))
def del_file(self, msg_dict): back_msg = {} users_info = self.get_file() del_path = msg_dict['file_path'] file_size = os.path.getsize(del_path) os.remove(r'{}'.format(del_path)) use_memory = self.space_calculate() users_info[msg_dict['user_id']]['use_space'] = use_memory users_info.write( open(r'%s\db\user_info.ini' % self.path, 'w', encoding=setting.CODING)) file_name = os.path.split(del_path)[1] back_msg['file_size'] = self.bytes(file_size) back_msg['file_name'] = file_name self.send_respond(state_code=402, **back_msg) log_msg = 'account:%s operation:del file file_name:%s info:del file successfully' % ( msg_dict['user_id'], file_name) loggers = Logger.logs('operation') loggers.info(log_msg) # 记录日志
def schooltime(role, account): ''' 老师上课打卡 :param account: :return: ''' while True: teacher_msg = Teacher_Function.get_data(role, account) print(teacher_msg) for i in teacher_msg['teacher_class']: class_msg = Teacher_Function.born_class('classes', i) print(class_msg) class_id = input('请输入要上课班级的代号(b退出)>>:').strip() # 选择上课班级 if class_id in teacher_msg['teacher_class']: log_msg = 'role:teacher account:%s operation:schooltime info:已在%s班级上课!' %\ (account, class_id) loggers = Logger.logs(role) loggers.info(log_msg) # 记录老师上课记录 return else: print('请输入正确班级代码!')
class OakleyForumDbExporter(object): def __init__(self, connection_pool): self.logger = Logger(self.__class__.__name__).get() self.connection_pool = connection_pool def export_database(self, export_path): export_name = 'sunglasses' self.logger.info( "Exporting whole database to export path [{}]".format(export_path)) query = "select f.name as family, s.name as model,m.name as colorway, m.framecolour as frame, l.name as lens, m.listprice," \ " m.sku, m.releasedate, m.retiredate, m.note, m.exclusive, m.signature from model m join lens l on" \ " m.lensid = l.id join style s on m.styleid=s.id join familystylemap x on x.styleid = s.id join" \ " family f on x.familyid = f.id" cnx = self.connection_pool.get_connection() cursor = cnx.cursor() cursor.execute(query) file_name = os.path.join(export_path, '{}.csv'.format(export_name)) self.logger.info("Export filename is [{}]".format(file_name)) headers = 'Type,Family,Model,Colorway,Frame,Lens,List Price,SKU,Release Date,Retire Date,Note:,Exclusive,Signature'.split( ',') with open(file_name, 'wb') as my_file: wr = UnicodeWriter(my_file) # header wr.writerow(headers) for item in cursor: item_list = list(item) item_list.insert(0, 'Sunglasses') for count in range(0, len(item_list)): if item_list[count] is None: item_list[count] = '' wr.writerow(item_list) cursor.close() self.connection_pool.release_connection(cnx) self.logger.info("Completed exporting table [{}]".format(export_name))
class Requests(object): _client_id = None _client_secret = None _logger = Logger() def config(self, client_id, client_secret): self._client_id = client_id self._client_secret = client_secret def get(self, endpoint, param=None, named_params=None): url = endpoint if param: url += param url += "?client_id=" + str(self._client_id) url += "&client_secret=" + str(self._client_secret) for p in named_params: url += "&" + p return requests.get(url).json() def validate(self, response): if response['meta']['code'] != 200: self._logger.log( Logger.ERROR, "GET Request Error Code " + str(response['meta']['code'])) self._logger.log( Logger.ERROR, "Error type: " + str(response['meta']['errorType'])) self._logger.log( Logger.ERROR, "Error detail: " + str(response['meta']['errorDetail'])) return False return True
def test_get_config_from_env(self): config = { "TYRBOT_BOTS_1_USERNAME": "******", "TYRBOT_BOTS_1_PASSWORD": "******", "TYRBOT_BOTS_1_CHARACTER": "character", "TYRBOT_BOTS_1_IS-MAIN": "true" } logger = Logger("test") result = core.functions.get_config_from_env(config, logger) expected = { 'bots': { '1': { 'username': '******', 'password': '******', 'character': 'character', 'is_main': True } } } self.assertEqual(expected, result)
def make_class(cls): ''' 添加班级 :return: ''' new_class = cls.creat_class() # 创建班级 choice_school = cls.select_school() # 给学校绑定班级 choice_course = cls.select_course('course', choice_school) # 给班级绑定课程 choice_teacher = cls.select_teacher(choice_course, choice_school) # 给班级绑定老师 new_class.structure['school'] = choice_school new_class.structure['class_course'] = choice_course new_class.structure['class_teacher'] = choice_teacher cls.save_file('classes', new_class.class_id, new_class.structure) # 保存班级信息 massage_teacher = cls.get_data('teacher', choice_teacher) massage_teacher['teacher_class'].append(new_class.class_id) cls.save_file('teacher', choice_teacher, massage_teacher) # 班级信息同步到老师 log_msg = 'role:admin account:admin operation:creat class info:%s创建成功' % new_class.class_name loggers = Logger.logs('manager') loggers.info(log_msg)
def create_bot_sessions(config: Dict) -> List[VKCoinBotSession]: bot_configs = config["bots"] bot_count = len(bot_configs) Logger.log_system(_("Found {} bots in config file").format(bot_count)) sessions = [] for bot_config in bot_configs: try: session = VKCoinBotSession(bot_config) session.setup() sessions.append(session) except Exception: Logger.log_error(_("Can not load bot with config #{}").format(bot_config)) if not sessions: Logger.log_error(_("No sessions created")) return sessions
def download(self, st): msg_dict = eval(st) user_id = msg_dict['user_id'] header_dict = { 'filename': msg_dict['file_path'], 'md5': 'xxxx', 'file_size': os.path.getsize(r'%s' % msg_dict['file_path']) } # 制作报头 header_json = json.dumps(header_dict) header_bytes = header_json.encode(setting.CODING) self.conn.send(struct.pack('i', len(header_bytes))) # 发送报头长度 self.conn.send(header_bytes) # 发送报头 with open(r'%s' % msg_dict['file_path'], 'rb') as f: # 发送下载文件内容 for line in f: self.conn.send(line) file_list = msg_dict['file_path'].split('\\') log_msg = 'account:%s operation:download file_name:%s info:download successfully' % \ (user_id, file_list[-1]) loggers = Logger.logs('operation') loggers.info(log_msg) # 记录日志
class WebsocketRelayWorker: def __init__(self, inbound_queue, url, user_agent): self.logger = Logger(__name__) self.inbound_queue = inbound_queue self.url = url self.ws = None self.user_agent = user_agent self.is_running = False def run(self): self.ws = create_connection(self.url, header={"User-Agent": self.user_agent}) self.logger.info("Connected to Websocket Relay!") self.is_running = True try: result = self.ws.recv() while result: obj = DictObject(json.loads(result)) self.inbound_queue.append(obj) result = self.ws.recv() except WebSocketConnectionClosedException as e: if self.is_running: self.logger.error("", e) self.ws.close() def send_message(self, message): if self.ws: self.ws.send(message) def send_ping(self): try: if self.ws: self.ws.ping() except WebSocketConnectionClosedException as e: self.logger.error("", e) self.close() def close(self): if self.ws: self.is_running = False self.ws.close()
def send_message(self, message, user): """ Envía el mensaje dado. """ try: # Si el mensaje no viene dado como corresponde. if not isinstance(message, GmailApiClient.MessageMapper): raise TypeError("The given message is not an instance of Message class.") Logger.info("Sending the message...") Logger.info("Message: {}".format(message)) # Obtenemos el mensaje en bruto y lo enviamos. response = self.messages().send( userId=user, body={"raw": message.get_raw_message()} ) except (errors.HttpError, TypeError), e: Logger.error(e) raise e
def move(self, character: Character): Logger.debug( "Following waypoint {} out of {}. Character is currently moving: {}" .format(character.current_waypoint, len(self.waypoints.waypoints) - 1, character.is_moving)) if character.position.is_close_to( self.waypoints.waypoints[character.current_waypoint], GlobalConfig.config.movement.waypoint_difference_threshold): Logger.debug("Close to waypoint") if character.current_waypoint == len(self.waypoints.waypoints) - 1: character.current_waypoint = 0 self.waypoints.reverse() else: character.current_waypoint += 1 if not self.turn(character): if not character.is_moving: Logger.debug('Moving') self.controller.move_forward() character.is_moving = True
def _check_through_screen(self, gen): Logger.debug("Entered loot state - Checking through screen") max_step_x = 20 max_step_y = 15 iter_x = int( (self.screen_res[2] - self.screen_res[0]) / max_step_x) + 1 iter_y = int( (self.screen_res[3] - self.screen_res[1]) / max_step_y) + 1 base_x = self.screen_res[0] base_y = self.screen_res[1] safe_zone = 3 max_step_x -= safe_zone max_step_y -= safe_zone Logger.debug( "Checking through screen: x-stepsize: {} y-stepsize: {}".format( iter_x, iter_y)) found = False while True: for i in range(safe_zone, max_step_x): x = base_x + iter_x * i for j in range(safe_zone * 2, max_step_y): # start from more downwards y = base_y + iter_y * j Logger.debug("Current x: {} current y: {}".format(x, y)) self.controller.move_mouse(x, y) current_screen = next(gen) found = self.scuttler.try_find( current_screen, ScreenObjects.LOOT_ICON.value) if found: self.controller.right_click() if not found: break if not found: self.finished_looting = True
class DriverHandler(object): # 根据配置文件配置初始化 webdriver def init_driver(self, log_name): # 读入配置文件 config_handler = ConfigParser() path = os.path.dirname(os.path.abspath('.')) + '/config.ini' config_handler.read(path) # 获取日志记录器 self.logger = Logger(logger=log_name).get_logger() # 获取配置文件属性 browser_name = config_handler.get('BrowserType', 'BrowserName') self.logger.info('You have choose the %s browser to driver.' % browser_name) self.url = config_handler.get('TestDomain', 'URL') self.logger.info('The testing Domain is %s' % self.url) exe_file = config_handler.get('WebDriver', 'Path') quiet_mode = config_handler.get('QuietMode', 'value') if browser_name == 'Firefox': self.driver = webdriver.Firefox() elif browser_name == 'Chrome': # 谷歌浏览器是否启用静默模式 if (int(quiet_mode) == 1): options = webdriver.ChromeOptions() options.add_argument('headless') self.driver = webdriver.Chrome(options=options) else: self.driver = webdriver.Chrome(exe_file) elif browser_name == 'IE': self.driver = webdriver.Ie(exe_file) return self.driver # 关闭并退出浏览器 def close_driver(self): self.logger.info('It\'s time to close the webdriver') self.driver.quit()
#==================================================================== # Imports #-------------------------------------------------------------------- import os import json import unittest import importlib from core.logger import Logger, SysTestResult from core.config import SysConfig, TestConfig #==================================================================== # Initializations #-------------------------------------------------------------------- configfile = 'config.json' #==================================================================== # Main Processing #-------------------------------------------------------------------- sc = SysConfig() sc.read_json(configfile) tcfg = TestConfig() runner = unittest.TextTestRunner(verbosity=0, resultclass=SysTestResult) result = runner.run(tcfg.testsuite) logger = Logger(sc, tcfg, result) logger.write2html()
class MappingDal(object): def __init__(self, connection_pool): self.logger = Logger(self.__class__.__name__).get() self.connection_pool = connection_pool def style_family_mapping_exists(self, style_id, family_id): mapping_id = self.get_style_family_mapping_id(style_id, family_id) return mapping_id != -1 def get_style_family_mapping_id(self, style_id, family_id): query = ("SELECT id, styleid, familyid FROM familystylemap " "WHERE styleid = %s " "AND familyid = %s " "AND validfrom < %s " "AND ((validto = '0000-00-00 00:00:00') OR (validto >= %s))") now = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime()) cnx = self.connection_pool.get_connection() cursor = cnx.cursor() data = (style_id, family_id, now, now) self.logger.debug("Getting mapping with query [%s] and data [%s]", query, data) cursor.execute(query, data) mapping_id = -1 for (c_id, c_styleid, c_familyid) in cursor: if c_styleid == style_id and c_familyid == family_id: mapping_id = c_id cursor.close() self.connection_pool.release_connection(cnx) return mapping_id def get_last_style_family_mapping_id(self): style_query = "SELECT MAX(id) FROM familystylemap" cnx = self.connection_pool.get_connection() cursor = cnx.cursor() cursor.execute(style_query) ret_id = -1 for c_id in cursor: if c_id is not None and c_id[0] is not None: ret_id = int(c_id[0]) cursor.close() self.connection_pool.release_connection(cnx) return ret_id def insert_style_family_mapping(self, style_id, family_id, source_id): query = ("INSERT INTO familystylemap " "(styleid, familyid, sourceid, validfrom) " "VALUES (%s, %s, %s, %s)") now = time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime()) cnx = self.connection_pool.get_connection() cursor = cnx.cursor() data = (style_id, family_id, source_id, now) cursor.execute(query, data) cnx.commit() mapping_id = int(cursor.lastrowid) cursor.close() self.connection_pool.release_connection(cnx) return mapping_id
from core.registry import Registry from core import config_creator from core.dict_object import DictObject from core.logger import Logger from core.aochat.mmdb_parser import MMDBParser import hjson import time import os try: # load logging configuration import conf.logging Registry.logger = Logger("core.registry") logger = Logger("core.bootstrap") logger.info("Starting Tyrbot...") config_file = "./conf/config.hjson" # start config wizard if config file does not exist if not os.path.exists(config_file): config_creator.create_new_cfg(config_file, "./conf/config.template.hjson") # load config logger.debug("Reading config file '%s'" % config_file) with open(config_file, "r") as cfg: config = DictObject(hjson.load(cfg)) # paths to search for instances: core + module_paths paths = ["core"]
class DiscordWrapper(discord.Client): def __init__(self, channel_name, dqueue, aoqueue): super().__init__(intents=discord.Intents(guilds=True, invites=True, guild_messages=True, dm_messages=True, members=True)) asyncio.set_event_loop(asyncio.new_event_loop()) self.logger = Logger(__name__) self.dqueue = dqueue self.aoqueue = aoqueue self.channel_name = channel_name self.default_channel = None async def logout_with_message(self, msg): if self.default_channel: await self.default_channel.send(msg) await super().logout() async def on_ready(self): self.set_channel_name(self.channel_name) self.dqueue.append(("discord_ready", "ready")) async def on_message(self, message): if not message.author.bot and ( self.default_channel and message.channel.id == self.default_channel.id or message.channel.type == ChannelType.private): self.dqueue.append(("discord_message", message)) async def relay_message(self): await self.wait_until_ready() while not self.is_closed(): if self.aoqueue: dtype, message = self.aoqueue.pop(0) try: if dtype == "get_invite": name = message[0] server = message[1] # TODO handle insufficient permissions invites = await self.get_guild(server.id).invites() self.dqueue.append( ("discord_invites", (name, invites))) else: content = message.get_message() channel = message.channel or self.default_channel if channel: if message.get_type() == "embed": await channel.send(embed=content) else: await channel.send(content) except Exception as e: self.logger.error( "Exception raised during Discord event (%s, %s)" % (str(dtype), str(message)), e) await asyncio.sleep(0.1) def set_channel_name(self, channel_name): self.channel_name = channel_name for channel in self.get_text_channels(): if channel.name == channel_name: self.default_channel = channel return True return False def get_text_channels(self): return list( filter(lambda x: x.type is ChannelType.text, self.get_all_channels()))
class CommandService: PRIVATE_MESSAGE_CHANNEL = "msg" def __init__(self): self.handlers = collections.defaultdict(list) self.logger = Logger(__name__) self.channels = {} self.pre_processors = [] self.ignore_regexes = [ re.compile(r" is AFK \(Away from keyboard\) since ", re.IGNORECASE), re.compile(r"I am away from my keyboard right now", re.IGNORECASE), re.compile(r"Unknown command or access denied!", re.IGNORECASE), re.compile(r"I am responding", re.IGNORECASE), re.compile(r"I only listen", re.IGNORECASE), re.compile(r"Error!", re.IGNORECASE), re.compile(r"Unknown command input", re.IGNORECASE), re.compile(r"You have been auto invited", re.IGNORECASE), re.compile(r"^<font") ] def inject(self, registry): self.db = registry.get_instance("db") self.util = registry.get_instance("util") self.access_service: AccessService = registry.get_instance( "access_service") self.bot = registry.get_instance("bot") self.character_service: CharacterService = registry.get_instance( "character_service") self.event_service = registry.get_instance("event_service") self.setting_service: SettingService = registry.get_instance( "setting_service") self.command_alias_service = registry.get_instance( "command_alias_service") self.usage_service = registry.get_instance("usage_service") self.public_channel_service = registry.get_instance( "public_channel_service") self.ban_service = registry.get_instance("ban_service") def pre_start(self): self.bot.register_packet_handler(server_packets.PrivateMessage.id, self.handle_private_message) self.register_command_channel("Private Message", self.PRIVATE_MESSAGE_CHANNEL) def start(self): access_levels = {} # process decorators for _, inst in Registry.get_all_instances().items(): for name, method in get_attrs(inst).items(): if hasattr(method, "command"): cmd_name, params, access_level, description, help_file, sub_command, extended_description = getattr( method, "command") handler = getattr(inst, name) help_text = self.get_help_file(inst.module_name, help_file) command_key = self.get_command_key( cmd_name.lower(), sub_command.lower() if sub_command else "") al = access_levels.get(command_key, None) if al is not None and al != access_level.lower(): raise Exception( "Different access levels specified for forms of command '%s'" % command_key) access_levels[command_key] = access_level self.register(handler, cmd_name, params, access_level, description, inst.module_name, help_text, sub_command, extended_description) def register(self, handler, command, params, access_level, description, module, help_text=None, sub_command=None, extended_description=None, check_access=None): """ Call during pre_start Args: handler: (request, param1, param2, ...) -> str|ChatBlob|None command: str params: [CommandParam...] access_level: str description: str module: str help_text: str sub_command: str extended_description: str check_access: (char_id, access_level_label) -> bool """ if len(inspect.signature(handler).parameters) != len(params) + 1: raise Exception( "Incorrect number of arguments for handler '%s.%s()'" % (handler.__module__, handler.__qualname__)) command = command.lower() if sub_command: sub_command = sub_command.lower() else: sub_command = "" access_level = access_level.lower() module = module.lower() command_key = self.get_command_key(command, sub_command) if help_text is None: help_text = self.generate_help(command, description, params, extended_description) if check_access is None: check_access = self.access_service.check_access if not self.access_service.get_access_level_by_label(access_level): self.logger.error( "Could not add command '%s': could not find access level '%s'" % (command, access_level)) return for channel, label in self.channels.items(): row = self.db.query_single( "SELECT access_level, module, enabled, verified " "FROM command_config " "WHERE command = ? AND sub_command = ? AND channel = ?", [command, sub_command, channel]) if row is None: # add new command self.db.exec( "INSERT INTO command_config " "(command, sub_command, access_level, channel, module, enabled, verified) " "VALUES (?, ?, ?, ?, ?, 1, 1)", [command, sub_command, access_level, channel, module]) elif row.verified: if row.module != module: self.logger.warning( "module different for different forms of command '%s' and sub_command '%s'" % (command, sub_command)) else: # mark command as verified self.db.exec( "UPDATE command_config SET verified = 1, module = ? " "WHERE command = ? AND sub_command = ? AND channel = ?", [module, command, sub_command, channel]) # save reference to command handler r = re.compile(self.get_regex_from_params(params), re.IGNORECASE | re.DOTALL) self.handlers[command_key].append({ "regex": r, "callback": handler, "help": help_text, "description": description, "params": params, "check_access": check_access }) def register_command_pre_processor(self, pre_processor): """ Call during start Args: pre_processor: (context) -> bool """ self.pre_processors.append(pre_processor) def register_command_channel(self, label, value): """ Call during pre_start Args: label: str value: str """ if value in self.channels: self.logger.error( "Could not register command channel '%s': command channel already registered" % value) return self.logger.debug("Registering command channel '%s'" % value) self.channels[value] = label def is_command_channel(self, channel): return channel in self.channels def process_command(self, message: str, channel: str, char_id, reply, conn): try: context = DictObject({ "message": message, "char_id": char_id, "channel": channel, "reply": reply }) for pre_processor in self.pre_processors: if pre_processor(context) is False: return for regex in self.ignore_regexes: if regex.search(message): return # message = html.unescape(message) command_str, command_args = self.get_command_parts(message) # check for command alias command_alias_str = self.command_alias_service.get_alias_command_str( command_str, command_args) alias_depth_count = 0 while command_alias_str: alias_depth_count += 1 command_str, command_args = self.get_command_parts( command_alias_str) command_alias_str = self.command_alias_service.get_alias_command_str( command_str, command_args) if alias_depth_count > 20: raise Exception( "Command alias infinite recursion detected for command '%s'" % message) cmd_configs = self.get_command_configs(command_str, channel, 1) access_level = self.access_service.get_access_level(char_id) sender = SenderObj( char_id, self.character_service.resolve_char_to_name( char_id, "Unknown(%d)" % char_id), access_level) if cmd_configs: # given a list of cmd_configs that are enabled, see if one has regex that matches incoming command_str cmd_config, matches, handler = self.get_matches( cmd_configs, command_args) if matches: if handler["check_access"](char_id, cmd_config.access_level): response = handler["callback"]( CommandRequest(conn, channel, sender, reply), *self.process_matches(matches, handler["params"])) if response is not None: reply(response) # record command usage self.usage_service.add_usage( command_str, self.util.get_handler_name(handler["callback"]), char_id, channel) else: self.access_denied_response(message, sender, cmd_config, reply) else: # handlers were found, but no handler regex matched data = self.db.query( "SELECT command, sub_command, access_level FROM command_config " "WHERE command = ? AND channel = ? AND enabled = 1", [command_str, channel]) help_text = self.format_help_text(data, char_id) if help_text: reply( self.format_help_text_blob(command_str, help_text)) else: # the command is known, but no help is returned, therefore character does not have access to command reply("Access denied.") else: self.handle_unknown_command(command_str, command_args, channel, sender, reply) except Exception as e: self.logger.error("error processing command: %s" % message, e) reply("There was an error processing your request.") def handle_unknown_command(self, command_str, command_args, channel, sender, reply): reply(f"Error! Unknown command <highlight>{command_str}</highlight>.") def access_denied_response(self, message, sender, cmd_config, reply): reply("Access denied.") def get_command_parts(self, message): parts = message.split(" ", 1) if len(parts) == 2: return parts[0].lower(), " " + parts[1] else: return parts[0].lower(), "" def get_command_configs(self, command, channel=None, enabled=1, sub_command=None): sql = "SELECT command, sub_command, access_level, channel, enabled FROM command_config WHERE command = ?" params = [command] if channel: sql += " AND channel = ?" params.append(channel) if enabled: sql += " AND enabled = ?" params.append(enabled) if sub_command: sql += " AND sub_command = ?" params.append(sub_command) sql += " ORDER BY sub_command, channel" return self.db.query(sql, params) def get_matches(self, cmd_configs, command_args): for row in cmd_configs: command_key = self.get_command_key(row.command, row.sub_command) handlers = self.handlers[command_key] for handler in handlers: matches = handler["regex"].search(command_args) if matches: return row, matches, handler return None, None, None def process_matches(self, matches, params): groups = list(matches.groups()) processed = [] for param in params: processed.append(param.process_matches(groups)) return processed def format_help_text(self, data, char_id, show_regex=False): # filter out commands that character does not have access level for data = filter( lambda row: self.access_service.check_access( char_id, row.access_level), data) def get_regex(params): if show_regex: return "\n" + self.get_regex_from_params(params) else: return "" def read_help_text(row): command_key = self.get_command_key(row.command, row.sub_command) return filter( lambda x: x is not None, map( lambda handler: handler["help"] + get_regex(handler[ "params"]), self.handlers[command_key])) content = "\n\n".join(flatmap(read_help_text, data)) return content if content else None def format_help_text_blob(self, topic, help_text): return ChatBlob("Help (" + topic + ")", help_text) def get_help_file(self, module, help_file): if help_file: try: help_file = "./" + module.replace(".", "/") + "/" + help_file with open(help_file, mode="r", encoding="UTF-8") as f: return f.read().strip() except FileNotFoundError as e: self.logger.error("Error reading help file", e) return None def get_command_key(self, command, sub_command): if sub_command: return command + ":" + sub_command else: return command def get_command_key_parts(self, command_str): parts = command_str.split(":", 1) if len(parts) == 2: return parts[0], parts[1] else: return parts[0], "" def get_regex_from_params(self, params): # params must be wrapped with line-beginning and line-ending anchors in order to match # when no params are specified (eg. "^$") return "^" + "".join(map(lambda x: x.get_regex(), params)) + "$" def generate_help(self, command, description, params, extended_description=None): help_text = description + ":\n" + "<tab><symbol>" + command + " " + " ".join( map(lambda x: x.get_name(), params)) if extended_description: help_text += "\n" + extended_description return help_text def get_handlers(self, command_key): return self.handlers.get(command_key, None) def handle_private_message(self, conn: Conn, packet: server_packets.PrivateMessage): if not self.setting_service.get("accept_commands_from_slave_bots" ).get_value() and not conn.is_main: return # since the command symbol is not required for private messages, # the command_str must have length of at least 1 in order to be valid, # otherwise it is ignored if len(packet.message) < 1: return # ignore leading space message = packet.message.lstrip() def reply(msg): if self.bot.mass_message_queue and FeatureFlags.FORCE_LARGE_MESSAGES_FROM_SLAVES and \ isinstance(msg, ChatBlob) and len(msg.msg) > FeatureFlags.FORCE_LARGE_MESSAGES_FROM_SLAVES_THRESHOLD: self.bot.send_mass_message(packet.char_id, msg, conn=conn) else: self.bot.send_private_message(packet.char_id, msg, conn=conn) self.process_command(self.trim_command_symbol(message), self.PRIVATE_MESSAGE_CHANNEL, packet.char_id, reply, conn) def trim_command_symbol(self, s): symbol = self.setting_service.get("symbol").get_value() if s.startswith(symbol): s = s[len(symbol):] return s
class OrgActivityController: def __init__(self): self.logger = Logger(__name__) def inject(self, registry): self.db = registry.get_instance("db") self.util = registry.get_instance("util") self.character_service = registry.get_instance("character_service") self.command_alias_service = registry.get_instance( "command_alias_service") def start(self): self.db.exec( "CREATE TABLE IF NOT EXISTS org_activity (id INT PRIMARY KEY AUTO_INCREMENT, actor_char_id INT NOT NULL, actee_char_id INT NOT NULL, " "action VARCHAR(20) NOT NULL, created_at INT NOT NULL)") self.command_alias_service.add_alias("orghistory", "orgactivity") @command(command="orgactivity", params=[], access_level="org_member", description="Show org member activity") def orgactivity_cmd(self, request): sql = """ SELECT p1.name AS actor, p2.name AS actee, o.action, o.created_at FROM org_activity o LEFT JOIN player p1 ON o.actor_char_id = p1.char_id LEFT JOIN player p2 ON o.actee_char_id = p2.char_id ORDER BY o.created_at DESC LIMIT 40 """ data = self.db.query(sql) blob = "" for row in data: blob += self.format_org_action(row) + "\n" return ChatBlob("Org Activity", blob) @event(PublicChannelService.ORG_MSG_EVENT, "Record org member activity", is_hidden=True) def org_msg_event(self, event_type, event_data): ext_msg = event_data.extended_message if [ext_msg.category_id, ext_msg.instance_id] == OrgMemberController.LEFT_ORG: self.save_activity(ext_msg.params[0], ext_msg.params[0], "left") elif [ext_msg.category_id, ext_msg.instance_id] == OrgMemberController.KICKED_FROM_ORG: self.save_activity(ext_msg.params[0], ext_msg.params[1], "kicked") elif [ext_msg.category_id, ext_msg.instance_id] == OrgMemberController.INVITED_TO_ORG: self.save_activity(ext_msg.params[0], ext_msg.params[1], "invited") elif [ext_msg.category_id, ext_msg.instance_id ] == OrgMemberController.KICKED_INACTIVE_FROM_ORG: self.save_activity(ext_msg.params[0], ext_msg.params[1], "removed") elif [ext_msg.category_id, ext_msg.instance_id ] == OrgMemberController.KICKED_ALIGNMENT_CHANGED: self.save_activity(ext_msg.params[0], ext_msg.params[0], "alignment changed") def save_activity(self, actor, actee, action): actor_id = self.character_service.resolve_char_to_id(actor) actee_id = self.character_service.resolve_char_to_id( actee) if actee else 0 if not actor_id: self.logger.error("Could not get char_id for actor '%s'" % actor) if not actee_id: self.logger.error("Could not get char_id for actee '%s'" % actee) t = int(time.time()) self.db.exec( "INSERT INTO org_activity (actor_char_id, actee_char_id, action, created_at) VALUES (?, ?, ?, ?)", [actor_id, actee_id, action, t]) def format_org_action(self, row): if row.action == "left" or row.action == "alignment changed": return "<highlight>%s</highlight> %s. %s" % ( row.actor, row.action, self.util.format_datetime( row.created_at)) else: return "<highlight>%s</highlight> %s <highlight>%s</highlight>. %s" % ( row.actor, row.action, row.actee, self.util.format_datetime(row.created_at))
from pts.action_manager import ActionManager from pts.scrobbler import Scrobbler from pts.session_manager import SessionManager from sync.sync_manager import SyncManager from plex import Plex from plex_activity import Activity from plex_metadata import Metadata, Matcher from requests.packages.urllib3.util import Retry from trakt import Trakt, ClientError import logging import os import time log = Logger() class Main(object): modules = [ # core UpdateChecker(), # pts ActionManager, Scrobbler, SessionManager(), # sync SyncManager, ]
def main(): options = ProgramOptions() logger = Logger(options) if options.command == ProgramCommands.LIST: logger.printLogs() elif options.command == ProgramCommands.ADD: logger.appendLog(options.message) elif options.command == ProgramCommands.EDIT: logger.editLogWithId(options.logId) elif options.command == ProgramCommands.DELETE: logger.deleteLogWithId(options.logId) elif options.command == ProgramCommands.LIST_TAGS: logger.listTags()
class MigrateController: DATABASE_TYPE_MYSQL = "mysql" DATABASE_TYPE_SQLITE = "sqlite" def __init__(self): self.logger = Logger(__name__) def inject(self, registry): self.bot = registry.get_instance("bot") self.db = registry.get_instance("db") self.character_service = registry.get_instance("character_service") self.alts_service = registry.get_instance("alts_service") self.pork_service = registry.get_instance("pork_service") @event(event_type="connect", description="Configure migration controller", is_system=True) def connect_event(self, event_type, event_data): self.db2 = DB() # Optional: the name of the bot character that the budabot/bebot ran as # if the bot name is the same, then you can leave this blank, otherwise you must fill in this value bot_name = "" # Optional: the org_id of the org # the bot will use the org_id of the primary conn if this is not set, which is usually correct org_id = 0 # if your budabot/bebot used mysql, then uncomment the second line below and fill out the appropriate values # otherwise, if your budabot used sqlite, then uncomment the first line below and enter the path to the sqlite db file # do NOT uncomment both of them # REQUIRED: uncomment ONE of these two lines below # self.db2.connect_sqlite("./data/budabot.db") # self.db2.connect_mysql(host="localhost", port=3306, username="", password="", database_name="") self.bot_name = bot_name.lower( ) if bot_name else self.bot.get_primary_conn().get_char_name().lower() self.org_id = org_id if org_id else self.bot.get_primary_conn().org_id self.dimension = self.bot.dimension # TODO in each command, check if db has been initialized properly first @command(command="bebot", params=[Const("migrate"), Const("alts")], access_level="superadmin", description="Migrate alts from a Bebot database") def migrate_bebot_alts_cmd(self, request, _1, _2): data = self.db2.query( "SELECT a.alt, u1.char_id AS alt_char_id, a.main, u2.char_id AS main_char_id " "FROM alts a " f"LEFT JOIN {self.bot_name}_users u1 ON a.alt = u1.nickname " f"LEFT JOIN {self.bot_name}_users u2 ON a.main = u2.nickname " "WHERE a.confirmed = 1 " "ORDER BY main, alt") current_main = None current_main_id = None count_inactive = 0 count_success = 0 count_failure = 0 request.reply("Processing %s alt records..." % len(data)) for row in data: if row.main != current_main: current_main = row.main current_main_id = self.resolve_to_char_id( row.main, row.main_char_id) if not current_main_id: self.logger.warning( f"Could not resolve main char '{current_main}' to char id") count_inactive += 1 continue alt_id = self.resolve_to_char_id(row.alt, row.alt_char_id) if not alt_id: self.logger.warning( f"Could not resolve alt char '{row.alt}' to char id") count_inactive += 1 continue msg, result = self.alts_service.add_alt(current_main_id, alt_id) if result: count_success += 1 else: count_failure += 1 return f"<highlight>{count_success}</highlight> alts were migrated successfully, " \ f"<highlight>{count_failure}</highlight> alts failed to be added, " \ f"and <highlight>{count_inactive}</highlight> chars were inactive and could not be resolved to char ids." @command(command="bebot", params=[Const("migrate"), Const("logon")], access_level="superadmin", description="Migrate logon messages from a Bebot database") def migrate_bebot_logon_cmd(self, request, _1, _2): data = self.db2.query(f"SELECT message, id FROM {self.bot_name}_logon") request.reply("Processing %s logon records..." % len(data)) for row in data: self.db.exec( "INSERT INTO log_messages (char_id, logon) VALUES(?, ?)", [row.id, row.message]) return f"Successfully migrated <highlight>%d</highlight> logon messages." % len( data) @command(command="budabot", params=[Const("migrate"), Const("admins")], access_level="superadmin", description="Migrate admins from a Budabot database") def migrate_budabot_admins_cmd(self, request, _1, _2): data = self.db2.query( "SELECT a.name, p.charid AS char_id, CASE WHEN adminlevel = 4 THEN 'admin' WHEN adminlevel = 3 THEN 'moderator' END AS access_level " f"FROM admin_{self.bot_name} a LEFT JOIN players p ON (a.name = p.name AND p.dimension = ?) " "WHERE p.charid > 0", [self.dimension]) with self.db.transaction(): for row in data: char_id = self.resolve_to_char_id(row.name, row.char_id) if char_id and row.access_level: self.db.exec("DELETE FROM admin WHERE char_id = ?", [char_id]) self.db.exec( "INSERT INTO admin (char_id, access_level) VALUES (?, ?)", [char_id, row.access_level]) return f"Successfully migrated <highlight>%d</highlight> admin characters." % len( data) @command(command="budabot", params=[Const("migrate"), Const("banlist")], access_level="superadmin", description="Migrate ban list from a Budabot database") def migrate_budabot_banlist_cmd(self, request, _1, _2): data = self.db2.query( "SELECT b.charid AS char_id, p.charid AS sender_char_id, time AS created_at, banend AS finished_at, reason " f"FROM banlist_{self.bot_name} b JOIN players p ON (b.admin = p.name AND p.dimension = ?)" "WHERE p.charid > 0", [self.dimension]) with self.db.transaction(): for row in data: self.db.exec("DELETE FROM ban_list WHERE char_id = ?", [row.char_id]) self.db.exec( "INSERT INTO ban_list (char_id, sender_char_id, created_at, finished_at, reason, ended_early) VALUES (?, ?, ?, ?, ?, ?)", [ row.char_id, row.sender_char_id, row.created_at, row.finished_at, row.reason, 0 ]) return f"Successfully migrated <highlight>%d</highlight> banned characters." % len( data) @command(command="budabot", params=[Const("migrate"), Const("alts")], access_level="superadmin", description="Migrate alts from a Budabot database") def migrate_budabot_alts_cmd(self, request, _1, _2): data = self.db2.query( "SELECT p1.charid AS main_char_id, p2.charid AS alt_char_id " "FROM alts a JOIN players p1 ON (p1.name = a.main AND p1.dimension = ?) " "JOIN players p2 ON (p2.name = a.alt AND p2.dimension = ?)" "WHERE validated = 1 AND p1.charid > 0 AND p2.charid > 0 ORDER BY a.main ASC", [self.dimension, self.dimension]) with self.db.transaction(): current_main = 0 group_id = 0 for row in data: if row.main_char_id != current_main: current_main = row.main_char_id group_id = self.db.query_single( "SELECT (COALESCE(MAX(group_id), 0) + 1) AS next_group_id FROM alts" ).next_group_id self.db.exec("DELETE FROM alts WHERE char_id = ?", [row.main_char_id]) self.db.exec( "INSERT INTO alts (char_id, group_id, status) VALUES (?, ?, ?)", [row.main_char_id, group_id, AltsService.MAIN]) self.db.exec("DELETE FROM alts WHERE char_id = ?", [row.alt_char_id]) self.db.exec( "INSERT INTO alts (char_id, group_id, status) VALUES (?, ?, ?)", [row.alt_char_id, group_id, AltsService.CONFIRMED]) return f"Successfully migrated <highlight>%d</highlight> alt characters." % len( data) @command(command="budabot", params=[Const("migrate"), Const("members")], access_level="superadmin", description="Migrate members from a Budabot database") def migrate_budabot_members_cmd(self, request, _1, _2): data = self.db2.query( "SELECT m.name AS sender, p.charid AS char_id, m.autoinv AS auto_invite " f"FROM members_{self.bot_name} m JOIN players p ON (m.name = p.name AND p.dimension = ?) " "WHERE p.charid > 0", [self.dimension]) num = 0 for row in data: char_id = self.resolve_to_char_id(row.sender, row.char_id) if char_id: num += 1 self.db.exec("DELETE FROM member WHERE char_id = ?", [row.char_id]) self.db.exec( "INSERT INTO member (char_id, auto_invite) VALUES (?, ?)", [row.char_id, row.auto_invite]) return f"Successfully migrated <highlight>{num}</highlight> members." @command(command="budabot", params=[Const("migrate"), Const("quotes")], access_level="superadmin", description="Migrate quotes from a Budabot database") def migrate_budabot_quotes_cmd(self, request, _1, _2): data = self.db2.query( "SELECT q.poster, p.charid AS char_id, q.id, q.msg, q.dt " "FROM quote q LEFT JOIN players p ON (q.poster = p.name AND p.dimension = ?)", [self.dimension]) count_inactive = 0 request.reply("Processing %s quote records..." % len(data)) for row in data: char_id = self.resolve_to_char_id(row.poster, row.char_id) if not char_id: char_id = -1 count_inactive += 1 self.db.exec("DELETE FROM quote WHERE id = ?", [row.id]) self.db.exec( "INSERT INTO quote (id, char_id, created_at, content) VALUES (?, ?, ?, ?)", [row.id, char_id, row.dt, row.msg]) return f"Quotes successfully migrated. <highlight>{count_inactive}</highlight> posters were inactive and could not be resolved to char ids." @command(command="budabot", params=[Const("migrate"), Const("log_messages")], access_level="superadmin", description="Migrate log messages from a Budabot database") def migrate_budabot_log_messages_cmd(self, request, _1, _2): data = self.db2.query( f"SELECT p2.charid AS char_id, p1.sender, p1.name, p1.value " f"FROM preferences_{self.bot_name} p1 LEFT JOIN players p2 ON (p1.sender = p2.name AND p2.dimension = ?) " "WHERE p1.name = 'logon_msg' OR p1.name = 'logoff_msg'", [self.dimension]) count_inactive = 0 count_logon = 0 count_logoff = 0 request.reply("Processing %s log messages records..." % len(data)) for row in data: char_id = self.resolve_to_char_id(row.sender, row.char_id) if not char_id: count_inactive += 1 else: existing = self.db.query_single( "SELECT 1 FROM log_messages WHERE char_id = ?", [char_id]) if not existing: self.db.exec( "INSERT INTO log_messages (char_id, logon, logoff) VALUES (?, NULL, NULL)", [char_id]) if row.name == 'logon_msg' and row.value: self.db.exec( "UPDATE log_messages SET logon = ? WHERE char_id = ?", [row.value, char_id]) count_logon += 1 elif row.name == 'logoff_msg' and row.value: self.db.exec( "UPDATE log_messages SET logoff = ? WHERE char_id = ?", [row.value, char_id]) count_logoff += 1 return f"<highlight>{count_logon}</highlight> logon and <highlight>{count_logoff}</highlight> logoff messages successfully migrated. " \ f"<highlight>{count_inactive}</highlight> messages were from inactive characters that could not be resolved to char ids." @command(command="budabot", params=[Const("migrate"), Const("name_history")], access_level="superadmin", description="Migrate name history from a Budabot database") def migrate_budabot_name_history_cmd(self, request, _1, _2): data = self.db2.query( "SELECT charid AS char_id, name, dt AS created_at FROM name_history" ) request.reply( "Processing %s name history records. This may take some time..." % len(data)) with self.db.transaction(): for row in data: self.db.exec( "DELETE FROM name_history WHERE char_id = ? AND name = ?", [row.char_id, row.name]) self.db.exec( "INSERT INTO name_history (char_id, name, created_at) VALUES (?, ?, ?)", [row.char_id, row.name, row.created_at]) return f"Successfully migrated <highlight>%d</highlight> name history records." % len( data) @command(command="budabot", params=[Const("migrate"), Const("news")], access_level="superadmin", description="Migrate news from a Budabot database") def migrate_budabot_news_cmd(self, request, _1, _2): data = self.db2.query( "SELECT n.name AS poster, p.charid AS char_id, news, sticky, time AS created_at, deleted AS deleted_at " "FROM news n JOIN players p ON (n.name = p.name AND p.dimension = ?) WHERE p.charid > 0", [self.dimension]) for row in data: char_id = self.resolve_to_char_id(row.poster, row.char_id) if not char_id: char_id = -1 self.db.exec("DELETE FROM news WHERE char_id = ? AND news = ?", [char_id, row.news]) self.db.exec( "INSERT INTO news (char_id, news, sticky, created_at, deleted_at) VALUES (?, ?, ?, ?, ?)", [ char_id, row.news, row.sticky, row.created_at, row.deleted_at ]) return f"Successfully migrated <highlight>%d</highlight> news records." % len( data) @command(command="budabot", params=[Const("migrate"), Const("notes")], access_level="superadmin", description="Migrate notes from a Budabot database") def migrate_budabot_notes_cmd(self, request, _1, _2): data = self.db2.query( "SELECT n.added_by AS sender, p.charid AS char_id, n.note, n.dt AS created_at " "FROM notes n JOIN players p ON (p.name = n.added_by AND p.dimension = ?) WHERE p.charid > 0", [self.dimension]) num = 0 for row in data: char_id = self.resolve_to_char_id(row.sender, row.char_id) if char_id: num += 1 self.db.exec( "DELETE FROM notes WHERE char_id = ? AND note = ?", [char_id, row.note]) self.db.exec( "INSERT INTO notes (char_id, note, created_at) VALUES (?, ?, ?)", [char_id, row.note, row.created_at]) return f"Successfully migrated <highlight>{num}</highlight> note records." @command(command="budabot", params=[Const("migrate"), Const("last_seen")], access_level="superadmin", description="Migrate last_seen data from a Budabot database") def migrate_budabot_last_seen_cmd(self, request, _1, _2): data = self.db2.query( "SELECT o.name AS sender, p.charid AS char_id, logged_off AS last_seen " f"FROM org_members_{self.bot_name} o JOIN players p ON (o.name = p.name AND p.dimension = ?) " "WHERE p.charid > 0", [self.dimension]) num = 0 with self.db.transaction(): for row in data: char_id = self.resolve_to_char_id(row.sender, row.char_id) if char_id: num += 1 self.db.exec("DELETE FROM last_seen WHERE char_id = ?", [char_id]) self.db.exec( "INSERT INTO last_seen (char_id, dt) VALUES (?, ?)", [char_id, row.last_seen]) return f"Successfully migrated <highlight>{num}</highlight> last seen records." @command(command="budabot", params=[Const("migrate"), Const("cloak_status")], access_level="superadmin", description="Migrate cloak status records from a Budabot database" ) def migrate_budabot_cloak_status_cmd(self, request, _1, _2): if not self.org_id: return "Could not migrate cloak status record since org id is not set." data = self.db2.query( "SELECT o.player AS name, p.charid AS char_id, action, time AS created_at " f"FROM org_city_{self.bot_name} o JOIN players p ON (o.player = p.name AND p.dimension = ?) " "WHERE p.charid > 0", [self.dimension]) num = 0 with self.db.transaction(): self.db.exec("DELETE FROM cloak_status WHERE org_id = ?", [self.org_id]) for row in data: char_id = self.resolve_to_char_id(row.name, row.char_id) if char_id: num += 1 self.db.exec( "INSERT INTO cloak_status (char_id, action, created_at, org_id) VALUES (?, ?, ?, ?)", [char_id, row.action, row.created_at, self.org_id]) return f"Successfully migrated <highlight>{num}</highlight> cloak status records." @command(command="budabot", params=[Const("migrate"), Const("org_activity")], access_level="superadmin", description="Migrate org activity records from a Budabot database" ) def migrate_budabot_org_activity_cmd(self, request, _1, _2): if not self.org_id: return "Could not migrate cloak status record since org id is not set." request.reply("Processing records. This may take some time...") data = self.db2.query( "SELECT o.actor AS actor_name, p1.charid AS actor_char_id, o.actee AS actee_name, p2.charid AS actee_char_id, action, time AS created_at " "FROM org_history o JOIN players p1 ON (o.actor = p1.name AND p1.dimension = ?) JOIN players p2 ON (o.actee = p2.name AND p2.dimension = ?) " "WHERE p1.charid > 0 AND p2.charid > 0", [self.dimension, self.dimension]) num = 0 with self.db.transaction(): self.db.exec("DELETE FROM org_activity WHERE org_id = ?", [self.org_id]) for row in data: actor_char_id = self.resolve_to_char_id( row.actor_name, row.actor_char_id) actee_char_id = self.resolve_to_char_id( row.actee_name, row.actee_char_id) if actor_char_id and actee_char_id: num += 1 self.db.exec( "INSERT INTO org_activity (actor_char_id, actee_char_id, action, created_at, org_id) VALUES (?, ?, ?, ?, ?)", [ actor_char_id, actee_char_id, row.action, row.created_at, self.org_id ]) return f"Successfully migrated <highlight>{num}</highlight> org activity records." @command( command="budabot", params=[Const("migrate"), Const("players")], access_level="superadmin", description="Migrate character info records from a Budabot database") def migrate_budabot_player_cmd(self, request, _1, _2): data = self.db2.query( "SELECT * FROM players WHERE charid > 0 AND dimension = ?", [self.dimension]) request.reply("Processing %s records. This may take some time..." % len(data)) num = 0 with self.db.transaction(): for row in data: if row.charid: num += 1 self.db.exec("DELETE FROM player WHERE char_id = ?", [row.charid]) self.db.exec( "INSERT INTO player (ai_level, ai_rank, breed, char_id, dimension, faction, first_name, gender, head_id, last_name, " "last_updated, level, name, org_id, org_name, org_rank_id, org_rank_name, profession, profession_title, pvp_rating, pvp_title, source) " "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", [ row.ai_level, row.ai_rank, row.breed, row.charid, row.dimension, row.faction, row.firstname, row.gender, row.head_id if row.head_id else 0, row.lastname, row.last_update, row.level, row.name, row.guild_id, row.guild, row.guild_rank_id or 0, row.guild_rank, row.profession, row.prof_title, row.pvp_rating if row.pvp_rating else 0, row.pvp_title if row.pvp_title else "", row.source ]) # maybe this is needed also? self.db.exec("DELETE FROM player WHERE char_id = 4294967295") return f"Successfully migrated <highlight>{num}</highlight> character info records." def resolve_to_char_id(self, name, char_id): if char_id and char_id > 0: return char_id char_id = self.character_service.resolve_char_to_id(name) if char_id: return char_id char_info = self.pork_service.get_character_info(name) if char_info: return char_info.char_id return None
def __init__(self, connection_pool): self.logger = Logger(self.__class__.__name__).get() self.connection_pool = connection_pool
class PrivateChannelService: PRIVATE_CHANNEL_MESSAGE_EVENT = "private_channel_message" JOINED_PRIVATE_CHANNEL_EVENT = "private_channel_joined" LEFT_PRIVATE_CHANNEL_EVENT = "private_channel_left" def __init__(self): self.logger = Logger(__name__) self.private_channel_chars = {} def inject(self, registry): self.bot = registry.get_instance("bot") self.event_service = registry.get_instance("event_service") self.character_service = registry.get_instance("character_service") self.access_service = registry.get_instance("access_service") def pre_start(self): self.event_service.register_event_type(self.JOINED_PRIVATE_CHANNEL_EVENT) self.event_service.register_event_type(self.LEFT_PRIVATE_CHANNEL_EVENT) self.event_service.register_event_type(self.PRIVATE_CHANNEL_MESSAGE_EVENT) self.bot.register_packet_handler(server_packets.PrivateChannelClientJoined.id, self.handle_private_channel_client_joined) self.bot.register_packet_handler(server_packets.PrivateChannelClientLeft.id, self.handle_private_channel_client_left) # priority must be above that of CommandService in order for relaying of commands to work correctly self.bot.register_packet_handler(server_packets.PrivateChannelMessage.id, self.handle_private_channel_message, priority=30) self.access_service.register_access_level("guest", 90, self.in_private_channel) def handle_private_channel_message(self, conn: Conn, packet: server_packets.PrivateChannelMessage): if conn.id != "main": return if packet.private_channel_id == self.bot.get_char_id(): char_name = self.character_service.get_char_name(packet.char_id) self.logger.log_chat("Private Channel", char_name, packet.message) self.event_service.fire_event(self.PRIVATE_CHANNEL_MESSAGE_EVENT, packet) def handle_private_channel_client_joined(self, conn: Conn, packet: server_packets.PrivateChannelClientJoined): if conn.id != "main": return if packet.private_channel_id == self.bot.get_char_id(): self.private_channel_chars[packet.char_id] = packet self.logger.log_chat("Private Channel", None, "%s joined the channel." % self.character_service.get_char_name(packet.char_id)) self.event_service.fire_event(self.JOINED_PRIVATE_CHANNEL_EVENT, packet) def handle_private_channel_client_left(self, conn: Conn, packet: server_packets.PrivateChannelClientLeft): if conn.id != "main": return if packet.private_channel_id == self.bot.get_char_id(): del self.private_channel_chars[packet.char_id] self.logger.log_chat("Private Channel", None, "%s left the channel." % self.character_service.get_char_name(packet.char_id)) self.event_service.fire_event(self.LEFT_PRIVATE_CHANNEL_EVENT, packet) def invite(self, char_id): if char_id != self.bot.get_char_id(): self.bot.send_packet(client_packets.PrivateChannelInvite(char_id)) def kick(self, char_id): if char_id != self.bot.get_char_id(): self.bot.send_packet(client_packets.PrivateChannelKick(char_id)) def kickall(self): self.bot.send_packet(client_packets.PrivateChannelKickAll()) def in_private_channel(self, char_id): return char_id in self.private_channel_chars def get_all_in_private_channel(self): return self.private_channel_chars
from core.logger import Logger from plugin.core.constants import PLUGIN_PREFIX from plugin.core.environment import translate as _ from plugin.core.filters import Filters from plugin.core.helpers.variable import normalize from plugin.managers.account import AccountManager from plugin.models import Account, Message, SyncResult from plugin.sync import SyncMode from plugin.sync.main import Sync, QueueError from ago import human from datetime import datetime from plex import Plex log = Logger('interface.m_sync') # NOTE: pad_title(...) is used to force the UI to use 'media-details-list' @route(PLUGIN_PREFIX + '/sync/accounts') @catch_errors def AccountsMenu(refresh=None, *args, **kwargs): oc = ObjectContainer(title2=_("Accounts"), no_cache=True) # Active sync status Active.create( oc, callback=Callback(AccountsMenu, refresh=timestamp()), )
from sync.sync_task import SyncTask from sync.pull import Pull from sync.push import Push from sync.synchronize import Synchronize from datetime import datetime from plex import Plex from plex_activity import Activity import gc import threading import traceback import time import uuid L, LF = localization('sync.manager') log = Logger('sync.manager') HANDLERS = [Pull, Push, Synchronize] # Maps interval option labels to their minute values (argh..) INTERVAL_MAP = { 'Disabled': None, '15 Minutes': 15, '30 Minutes': 30, 'Hour': 60, '3 Hours': 180, '6 Hours': 360, '12 Hours': 720, 'Day': 1440, 'Week': 10080, }
from core.helpers import build_repr, try_convert from core.logger import Logger from urlparse import urlparse SHOW_AGENTS = [ 'com.plexapp.agents.thetvdb', 'com.plexapp.agents.thetvdbdvdorder', 'com.plexapp.agents.abstvdb', 'com.plexapp.agents.xbmcnfotv', 'com.plexapp.agents.mcm' ] log = Logger('plex.plex_objects') class PlexParsedGuid(object): def __init__(self, agent, sid, extra): self.agent = agent self.sid = sid self.extra = extra # Show self.season = None self.episode = None @classmethod def from_guid(cls, guid): if not guid: return None
from core.db import DB from core.logger import Logger from core.registry import Registry db = Registry.get_instance("db") bot = Registry.get_instance("bot") logger = Logger("core.upgrade") def table_info(table_name): if db.type == DB.MYSQL: data = db.query("DESCRIBE %s" % table_name) def normalize_table_info(row): row.name = row.Field row.type = row.Type.upper() return row return list(map(normalize_table_info, data)) elif db.type == DB.SQLITE: return db.query("PRAGMA table_info(%s)" % table_name) else: raise Exception("Unknown database type '%s'" % db.type) def table_exists(table_name): try: db.query("SELECT * FROM %s LIMIT 1" % table_name) return True except Exception:
class CommandService: PRIVATE_CHANNEL = "priv" ORG_CHANNEL = "org" PRIVATE_MESSAGE = "msg" def __init__(self): self.handlers = collections.defaultdict(list) self.logger = Logger(__name__) self.channels = {} self.ignore_regexes = [ re.compile(" is AFK \(Away from keyboard\) since ", re.IGNORECASE), re.compile("I am away from my keyboard right now", re.IGNORECASE), re.compile("Unknown command or access denied!", re.IGNORECASE), re.compile("I am responding", re.IGNORECASE), re.compile("I only listen", re.IGNORECASE), re.compile("Error!", re.IGNORECASE), re.compile("Unknown command input", re.IGNORECASE), re.compile("You have been auto invited", re.IGNORECASE), ] def inject(self, registry): self.db = registry.get_instance("db") self.util = registry.get_instance("util") self.access_service: AccessService = registry.get_instance( "access_service") self.bot: Tyrbot = registry.get_instance("bot") self.character_service: CharacterService = registry.get_instance( "character_service") self.setting_service: SettingService = registry.get_instance( "setting_service") self.command_alias_service = registry.get_instance( "command_alias_service") self.usage_service = registry.get_instance("usage_service") self.public_channel_service = registry.get_instance( "public_channel_service") self.ban_service = registry.get_instance("ban_service") def pre_start(self): self.bot.add_packet_handler(server_packets.PrivateMessage.id, self.handle_private_message) self.bot.add_packet_handler(server_packets.PrivateChannelMessage.id, self.handle_private_channel_message) self.bot.add_packet_handler(server_packets.PublicChannelMessage.id, self.handle_public_channel_message) self.register_command_channel("Private Message", self.PRIVATE_MESSAGE) self.register_command_channel("Org Channel", self.ORG_CHANNEL) self.register_command_channel("Private Channel", self.PRIVATE_CHANNEL) def start(self): # process decorators for _, inst in Registry.get_all_instances().items(): for name, method in get_attrs(inst).items(): if hasattr(method, "command"): cmd_name, params, access_level, description, help_file, sub_command, extended_description, check_access, aliases = getattr( method, "command") handler = getattr(inst, name) module = self.util.get_module_name(handler) help_text = self.get_help_file(module, help_file) self.register(handler, cmd_name, params, access_level, description, module, help_text, sub_command, extended_description, check_access) if len(inspect.signature( handler).parameters) != len(params) + 1: raise Exception( "Incorrect number of arguments for handler '%s.%s()'" % (handler.__module__, handler.__name__)) if aliases: for alias in aliases: self.command_alias_service.add_alias( alias, cmd_name) def register(self, handler, command, params, access_level, description, module, help_text=None, sub_command=None, extended_description=None, check_access=None): command = command.lower() if sub_command: sub_command = sub_command.lower() else: sub_command = "" access_level = access_level.lower() module = module.lower() command_key = self.get_command_key(command, sub_command) if help_text is None: help_text = self.generate_help(command, description, params, extended_description) if check_access is None: check_access = self.access_service.check_access if not self.access_service.get_access_level_by_label(access_level): self.logger.error( "Could not add command '%s': could not find access level '%s'" % (command, access_level)) return for channel, label in self.channels.items(): row = self.db.query_single( "SELECT access_level, module, enabled, verified " "FROM command_config " "WHERE command = ? AND sub_command = ? AND channel = ?", [command, sub_command, channel]) if row is None: # add new command commands self.db.exec( "INSERT INTO command_config " "(command, sub_command, access_level, channel, module, enabled, verified) " "VALUES (?, ?, ?, ?, ?, 1, 1)", [command, sub_command, access_level, channel, module]) elif row.verified: if row.module != module: self.logger.warning( "module different for different forms of command '%s' and sub_command '%s'" % (command, sub_command)) else: # mark command as verified self.db.exec( "UPDATE command_config SET verified = 1, module = ? " "WHERE command = ? AND sub_command = ? AND channel = ?", [module, command, sub_command, channel]) # save reference to command handler r = re.compile(self.get_regex_from_params(params), re.IGNORECASE | re.DOTALL) self.handlers[command_key].append({ "regex": r, "callback": handler, "help": help_text, "description": description, "params": params, "check_access": check_access }) def register_command_channel(self, label, value): if value in self.channels: self.logger.error( "Could not register command channel '%s': command channel already registered" % value) return self.logger.debug("Registering command channel '%s'" % value) self.channels[value] = label def is_command_channel(self, channel): return channel in self.channels def process_command(self, message: str, channel: str, char_id, reply): try: if self.ban_service.get_ban(char_id): # do nothing if character is banned self.logger.info( "ignored banned character %d for command '%s'" % (char_id, message)) return message = html.unescape(message) command_str, command_args = self.get_command_parts(message) # check for command alias command_alias = self.command_alias_service.check_for_alias( command_str) if command_alias: command_str, command_args = self.get_command_parts( command_alias + command_args) cmd_configs = self.get_command_configs(command_str, channel, 1) if cmd_configs: # given a list of cmd_configs that are enabled, see if one has regex that matches incoming command_str cmd_config, matches, handler = self.get_matches( cmd_configs, command_args) if matches: if handler["check_access"](char_id, cmd_config.access_level): sender = SenderObj( char_id, self.character_service.resolve_char_to_name( char_id, "Unknown(%d)" % char_id)) response = handler["callback"]( CommandRequest(channel, sender, reply), *self.process_matches(matches, handler["params"])) if response is not None: reply(response) # record command usage self.usage_service.add_usage( command_str, handler["callback"].__qualname__, char_id, channel) else: self.access_denied_response(char_id, cmd_config, reply) else: # handlers were found, but no handler regex matched help_text = self.get_help_text(char_id, command_str, channel) if help_text: reply(self.format_help_text(command_str, help_text)) else: reply("Error! Invalid syntax.") else: reply("Error! Unknown command <highlight>%s<end>." % command_str) except Exception as e: self.logger.error("error processing command: %s" % message, e) reply("There was an error processing your request.") def access_denied_response(self, char_id, cmd_config, reply): reply("Error! Access denied.") def get_command_parts(self, message): parts = message.split(" ", 1) if len(parts) == 2: return parts[0].lower(), " " + parts[1] else: return parts[0].lower(), "" def get_command_configs(self, command, channel=None, enabled=1, sub_command=None): sql = "SELECT command, sub_command, access_level, enabled FROM command_config WHERE command = ?" params = [command] if channel: sql += " AND channel = ?" params.append(channel) if enabled: sql += " AND enabled = ?" params.append(enabled) if sub_command: sql += " AND sub_command = ?" params.append(sub_command) sql += " ORDER BY sub_command, channel" return self.db.query(sql, params) def get_matches(self, cmd_configs, command_args): for row in cmd_configs: command_key = self.get_command_key(row.command, row.sub_command) handlers = self.handlers[command_key] for handler in handlers: # add leading space to search string to normalize input for command params matches = handler["regex"].search(command_args) if matches: return row, matches, handler return None, None, None def process_matches(self, matches, params): groups = list(matches.groups()) processed = [] for param in params: processed.append(param.process_matches(groups)) return processed def get_help_text(self, char, command_str, channel): data = self.db.query( "SELECT command, sub_command, access_level FROM command_config " "WHERE command = ? AND channel = ? AND enabled = 1", [command_str, channel]) # filter out commands that character does not have access level for data = filter( lambda row: self.access_service.check_access( char, row.access_level), data) def read_help_text(row): command_key = self.get_command_key(row.command, row.sub_command) return filter( lambda x: x is not None, map(lambda handler: handler["help"], self.handlers[command_key])) content = "\n\n".join(flatmap(read_help_text, data)) return content if content else None def format_help_text(self, topic, help_text): return ChatBlob("Help (" + topic + ")", help_text) def get_help_file(self, module, help_file): if help_file: try: help_file = "./" + module.replace(".", "/") + "/" + help_file with open(help_file) as f: return f.read().strip() except FileNotFoundError as e: self.logger.error("Error reading help file", e) return None def get_command_key(self, command, sub_command): if sub_command: return command + ":" + sub_command else: return command def get_command_key_parts(self, command_str): parts = command_str.split(":", 1) if len(parts) == 2: return parts[0], parts[1] else: return parts[0], "" def get_regex_from_params(self, params): # params must be wrapped with line-beginning and line-ending anchors in order to match # when no params are specified (eg. "^$") return "^" + "".join(map(lambda x: x.get_regex(), params)) + "$" def generate_help(self, command, description, params, extended_description=None): help_text = description + ":\n" + "<tab><symbol>" + command + " " + " ".join( map(lambda x: x.get_name(), params)) if extended_description: help_text += "\n" + extended_description return help_text def get_handlers(self, command_key): return self.handlers.get(command_key, None) def handle_private_message(self, packet: server_packets.PrivateMessage): # since the command symbol is not required for private messages, # the command_str must have length of at least 1 in order to be valid, # otherwise it is ignored if len(packet.message) < 1: return for regex in self.ignore_regexes: if regex.search(packet.message): return if packet.message[:1] == self.setting_service.get( "symbol").get_value(): command_str = packet.message[1:] else: command_str = packet.message self.process_command( command_str, self.PRIVATE_MESSAGE, packet.char_id, lambda msg: self.bot.send_private_message(packet.char_id, msg)) def handle_private_channel_message( self, packet: server_packets.PrivateChannelMessage): # since the command symbol is required in the private channel, # the command_str must have length of at least 2 in order to be valid, # otherwise it is ignored if len(packet.message) < 2: return symbol = packet.message[:1] command_str = packet.message[1:] if symbol == self.setting_service.get("symbol").get_value( ) and packet.private_channel_id == self.bot.char_id: self.process_command( command_str, self.PRIVATE_CHANNEL, packet.char_id, lambda msg: self.bot.send_private_channel_message(msg)) def handle_public_channel_message( self, packet: server_packets.PublicChannelMessage): # since the command symbol is required in the org channel, # the command_str must have length of at least 2 in order to be valid, # otherwise it is ignored if len(packet.message) < 2: return symbol = packet.message[:1] command_str = packet.message[1:] if symbol == self.setting_service.get("symbol").get_value( ) and self.public_channel_service.is_org_channel_id(packet.channel_id): self.process_command(command_str, self.ORG_CHANNEL, packet.char_id, lambda msg: self.bot.send_org_message(msg))
self.dense1 = nn.Linear(800, 500) self.relu3 = nn.ReLU() self.dense2 = nn.Linear(500, 10) fmt = {'tr_loss': '3.1e', 'tr_acc': '.4f', 'te_acc_det': '.4f', 'te_acc_stoch': '.4f', 'te_acc_ens': '.4f', 'te_nll_det': '.4f', 'te_nll_stoch': '.4f', 'te_nll_ens': '.4f', 'time': '.3f'} logger = Logger("lenet5-DO", fmt=fmt) net = LeNet5() net.cuda() logger.print(net) trainset = torchvision.datasets.MNIST(root='./data', train=True, download=True, transform=transforms.ToTensor()) trainloader = torch.utils.data.DataLoader(trainset, batch_size=200, shuffle=True, num_workers=4, pin_memory=True) testset = torchvision.datasets.MNIST(root='./data', train=False, download=True, transform=transforms.ToTensor()) testloader = torch.utils.data.DataLoader(testset, batch_size=200, shuffle=False, num_workers=4, pin_memory=True)
def __init__(self): self.logger = Logger(__name__) self.private_channel_chars = {}
class PrivateChannelService: PRIVATE_CHANNEL_MESSAGE_EVENT = "private_channel_message" JOINED_PRIVATE_CHANNEL_EVENT = "private_channel_joined" LEFT_PRIVATE_CHANNEL_EVENT = "private_channel_left" def __init__(self): self.logger = Logger(__name__) self.private_channel_chars = {} def inject(self, registry): self.bot = registry.get_instance("bot") self.event_service = registry.get_instance("event_service") self.character_service = registry.get_instance("character_service") def pre_start(self): self.event_service.register_event_type( self.JOINED_PRIVATE_CHANNEL_EVENT) self.event_service.register_event_type(self.LEFT_PRIVATE_CHANNEL_EVENT) self.event_service.register_event_type( self.PRIVATE_CHANNEL_MESSAGE_EVENT) self.bot.add_packet_handler( server_packets.PrivateChannelClientJoined.id, self.handle_private_channel_client_joined) self.bot.add_packet_handler(server_packets.PrivateChannelClientLeft.id, self.handle_private_channel_client_left) self.bot.add_packet_handler(server_packets.PrivateChannelMessage.id, self.handle_private_channel_message) def handle_private_channel_message( self, packet: server_packets.PrivateChannelMessage): if packet.private_channel_id == self.bot.char_id: char_name = self.character_service.get_char_name(packet.char_id) self.logger.log_chat("Private Channel", char_name, packet.message) self.event_service.fire_event(self.PRIVATE_CHANNEL_MESSAGE_EVENT, packet) def handle_private_channel_client_joined( self, packet: server_packets.PrivateChannelClientJoined): if packet.private_channel_id == self.bot.char_id: self.private_channel_chars[packet.char_id] = packet self.logger.log_chat( "Private Channel", None, "%s joined the channel." % self.character_service.get_char_name(packet.char_id)) self.event_service.fire_event(self.JOINED_PRIVATE_CHANNEL_EVENT, packet) def handle_private_channel_client_left( self, packet: server_packets.PrivateChannelClientLeft): if packet.private_channel_id == self.bot.char_id: del self.private_channel_chars[packet.char_id] self.logger.log_chat( "Private Channel", None, "%s left the channel." % self.character_service.get_char_name(packet.char_id)) self.event_service.fire_event(self.LEFT_PRIVATE_CHANNEL_EVENT, packet) def invite(self, char_id): if char_id != self.bot.char_id: self.bot.send_packet(client_packets.PrivateChannelInvite(char_id)) def kick(self, char_id): if char_id != self.bot.char_id: self.bot.send_packet(client_packets.PrivateChannelKick(char_id)) def kickall(self): self.bot.send_packet(client_packets.PrivateChannelKickAll()) def in_private_channel(self, char_id): return char_id in self.private_channel_chars
def __init__(self): self.logger = Logger(__name__)
def __init__(self): self.logger = Logger("tower_controller")