class MatrixBackend(ErrBot): def __init__(self, config): super().__init__(config) identity = config.BOT_IDENTITY self.token = identity["token"] self.url = identity["url"] self.user = identity["user"] self._client = None def build_identifier(self, text_representation: str) -> None: """Return an object that idenfifies a matrix person or room.""" pass @staticmethod def parse_identfier_pieces(regex: str, text_rep: str): m = re.match(regex, text_rep) if m: data, domain = m.group() return data, domain return None, None @staticmethod def parse_identfier(text_rep): """Parse matrix identifiers into usable types. Expected formats are as follows: !<room>:<domain> #<room>:<domain> @<user>:<domain> """ room, domain, user = None, None, None room, domain = MatrixBackend.parse_identfier_pieces( r"[!#](.*):(.*)", text_rep) if not room or not domain: user, domain = MatrixBackend.parse_identfier_pieces( r"@:(.*):(.*)", text_rep) return room, domain, user def send_msg(self, room_id, msg): room = self._client.join_room(room_id) return room.send_text(msg) def send_file(self, room_id, file_path, filename): with open(file_path, "rb") as f: content = f.read() return self.send_stream_content(room_id, content, filename) def send_stream_content(self, room_id, content, filename): res = self._client.upload(content, 'application/octet-stream', filename) room = self._client.join_room(room_id) room.send_file(res, filename) return res def build_reply(self, msg, text=None, private=False, threaded=False): response = self.build_message(text) response.frm = self.bot_identifier self.send_msg(msg.extras['room_id'], text) if private: response.to = msg.frm else: response.to = msg.frm.room if isinstance(msg.frm, RoomOccupant) else msg.frm return response def change_presence(self): pass def mode(self): pass def query_room(self): pass def rooms(self): pass def invite_callback(self, *args, **kwargs): print(args, kwargs) def ephemeral_callback(self, *args, **kwargs): print(args, kwargs) def leave_callback(self, *args, **kwargs): print(args, kwargs) def presence_callback(self, *args, **kwargs): print(args, kwargs) def callback(self, *events): for event in events: log.debug("Saw event %s.", event) if event["type"] == "m.room.message": content = event["content"] sender = event["sender"] if content["msgtype"] == "m.text": msg = Message(content["body"], extras={'room_id': event["room_id"]}) msg.frm = MatrixPerson(self._client, sender) msg.to = self.bot_identifier self.callback_message(msg) def serve_once(self): self._client = MatrixClient(self.url, token=self.token, user_id=self.user) self._client.add_listener(self.callback) self._client.add_invite_listener(self.invite_callback) self._client.add_ephemeral_listener(self.ephemeral_callback) self._client.add_leave_listener(self.leave_callback) self._client.add_presence_listener(self.presence_callback) self.connect_callback() self.bot_identifier = MatrixPerson(self._client, self.user) self._client.listen_forever()
def main(): global client global data global log global lock lock = threading.RLock() log.debug("try lock before main load_data()") with lock: log.debug("success lock before main load_data()") data=load_data() log.debug("release lock() after access global data") log.info("try init matrix-client") client = MatrixClient(conf.server) log.info("success init matrix-client") try: log.info("try login matrix-client") token = client.login(username=conf.username, password=conf.password,device_id=conf.device_id) log.info("success login matrix-client") except MatrixRequestError as e: print(e) log.debug(e) if e.code == 403: log.error("Bad username or password.") sys.exit(4) else: log.error("Check your sever details are correct.") sys.exit(2) except MissingSchema as e: log.error("Bad URL format.") print(e) log.debug(e) sys.exit(3) log.info("try init listeners") client.add_listener(on_message) client.add_ephemeral_listener(on_event) client.add_invite_listener(on_invite) client.start_listener_thread(exception_handler=exception_handler) log.info("success init listeners") try: x=0 log.info("enter main loop") while True: if conf.type_translate == "yandex_long": # check yandex_long_jobs: num_jobs=0 for room_id in data["rooms"]: if "jobs" in data["rooms"][room_id]: for job in data["rooms"][room_id]["jobs"]: ret_value=False num_jobs+=1 ret_value=check_long_yandex_job(log,room_id,data["rooms"][room_id]["jobs"],job) if ret_value==False: log.error("check_long_yandex_job(), room_id=%s, job_id=%s"%(room_id,job["id"])) result_string="error get result from yandex speech api - yandex api error" log.error(result_string) if send_notice(room_id,result_string)==False: log.error("send_notice(%s)"%room_id) if num_jobs > 0: log.debug("len jobs list for all rooms = %d"%num_jobs) time.sleep(3) except Exception as e: log.error(get_exception_traceback_descr(e)) log.error("exception at main loop check jobs: %s"%e) sys.exit(1) log.info("exit main loop")
def main(): global client global data global log global lock lock = threading.RLock() log.debug("try lock before main load_data()") with lock: log.debug("success lock before main load_data()") data = load_data() #FIXME отладка парсера #data["users"]["@progserega:matrix.org"]={} #data["users"]["@progserega:matrix.org"]["test"]={} #data["users"]["@progserega:matrix.org"]["test"]["alarms"]=[] #data["users"]["@progserega:matrix.org"]["test"]["lang"]="ru" #print(process_alarm_cmd("@progserega:matrix.org","test","напомни послезавтра после работы проверить звук в машине и подтёки масла, т.к. 11 июня закончится гарантия.")) #sys.exit(1) log.info("try init matrix-client") client = MatrixClient(conf.server) log.info("success init matrix-client") try: log.info("try login matrix-client") client.login_with_password(username=conf.username, password=conf.password) log.info("success login matrix-client") except MatrixRequestError as e: print(e) log.debug(e) if e.code == 403: log.error("Bad username or password.") sys.exit(4) else: log.error("Check your sever details are correct.") sys.exit(2) except MissingSchema as e: log.error("Bad URL format.") print(e) log.debug(e) sys.exit(3) log.info("try init listeners") client.add_listener(on_message) client.add_ephemeral_listener(on_event) client.add_invite_listener(on_invite) #client.start_listener_thread() # Слушанье сокета и пересоединение в случае сбоя: #client.listen_forever(timeout_ms=30000, exception_handler=exception_handler,bad_sync_timeout=5) client.start_listener_thread(exception_handler=exception_handler) #client.listen_forever(timeout_ms=30000, exception_handler=exception_handler,bad_sync_timeout=5) #client.listen_forever() log.info("success init listeners") x = 0 log.info("enter main loop") while True: # Проверяем уведомления: log.debug("try lock before main loop") with lock: log.debug("success lock before main loop") for user in data["users"]: for room in data["users"][user]: for item in data["users"][user][room]["alarms"]: alarm_timestamp = item["time"] alarm_text = item["text"] time_now = time.time() if alarm_timestamp < time_now: # Уведомляем: html = "<p><strong>Напоминаю Вам:</strong></p>\n<ul>\n" html += "<li>%s</li>\n" % alarm_text html += "</ul>\n" if send_html(room, html) == True: data["users"][user][room]["alarms"].remove( item) save_data(data) break # выходим из текущего цикла, т.к. изменили количество в маассиве (валится в корку) - следующей проверкой проверим оставшиеся else: log.error( "error send alarm at '%s' with text: '%s'" % (time.strftime( "%Y.%m.%d-%T", time.localtime(alarm_timestamp)), alarm_text)) #print("step %d"%x) #x+=1 time.sleep(10) log.info("exit main loop")