Обновление на 4.25
							parent
							
								
									0aeaed5f18
								
							
						
					
					
						commit
						9c315d6f35
					
				
							
								
								
									
										90
									
								
								bot_io.py
								
								
								
								
							
							
						
						
									
										90
									
								
								bot_io.py
								
								
								
								
							|  | @ -1,5 +1,5 @@ | ||||||
| # Bot I/O v1.70 | # Bot I/O v1.82 | ||||||
| # 14/06/2021 | # 15/11/2021 | ||||||
| # https://t.me/ssleg  © 2020 – 2021 | # https://t.me/ssleg  © 2020 – 2021 | ||||||
| 
 | 
 | ||||||
| import logging | import logging | ||||||
|  | @ -20,7 +20,7 @@ client: TelegramClient | ||||||
| msk_hour = timedelta(hours=3) | msk_hour = timedelta(hours=3) | ||||||
| sys_wait = 0.045 | sys_wait = 0.045 | ||||||
| 
 | 
 | ||||||
| manager_runned = GlobalFlag() | manager_run = GlobalFlag() | ||||||
| work_queue = OutMessagesQueue() | work_queue = OutMessagesQueue() | ||||||
| tg_flood_wait = GlobalFlag() | tg_flood_wait = GlobalFlag() | ||||||
| last_send_time: datetime | last_send_time: datetime | ||||||
|  | @ -54,7 +54,7 @@ class IncomingMessagesTimeBuffer: | ||||||
|         self.__buf = [] |         self.__buf = [] | ||||||
|         self.__size = size |         self.__size = size | ||||||
|         self.__user_id = user_id |         self.__user_id = user_id | ||||||
|         cursor.execute('select ban_count, ban_to_date from banlist where user_id=?', (user_id,)) |         cursor.execute('select ban_count, ban_to_date from ban_list where user_id=?', (user_id,)) | ||||||
|         row = cursor.fetchone() |         row = cursor.fetchone() | ||||||
|         if row is not None: |         if row is not None: | ||||||
|             self.__banned_to = datetime.strptime(row[1], '%Y-%m-%d %H:%M:%S') |             self.__banned_to = datetime.strptime(row[1], '%Y-%m-%d %H:%M:%S') | ||||||
|  | @ -80,15 +80,16 @@ class IncomingMessagesTimeBuffer: | ||||||
|     def __is_valid_timing(self, mess_date): |     def __is_valid_timing(self, mess_date): | ||||||
|         i = self.__size - 1 |         i = self.__size - 1 | ||||||
|         sec = 0 |         sec = 0 | ||||||
|         while i > self.__size - 4: |         # while i > self.__size - 4: | ||||||
|  |         while i > 5: | ||||||
|             prev_date = self.__buf[i][1] |             prev_date = self.__buf[i][1] | ||||||
|             if prev_date != 0: |             if prev_date != 0: | ||||||
|                 tmp = mess_date - prev_date |                 tmp = mess_date - prev_date | ||||||
|                 if tmp.seconds < 1: |                 '''if tmp.seconds < 1: | ||||||
|                     levent = 'обнаружено слишком частое обращение: ' + str(tmp.seconds) + ' сек.' |                     levent = 'обнаружено слишком частое обращение: ' + str(tmp.seconds) + ' сек.' | ||||||
|                     logging.warning(levent) |                     logging.warning(levent) | ||||||
|                     return False |                     return False | ||||||
|                 else: |                 else:''' | ||||||
|                 sec += tmp.seconds |                 sec += tmp.seconds | ||||||
|                 mess_date = prev_date |                 mess_date = prev_date | ||||||
|             else: |             else: | ||||||
|  | @ -98,7 +99,7 @@ class IncomingMessagesTimeBuffer: | ||||||
|         if sec >= 5: |         if sec >= 5: | ||||||
|             return True |             return True | ||||||
|         else: |         else: | ||||||
|             levent = 'обнаружены 4 сообщенния за ' + str(sec) + ' сек.' |             levent = 'обнаружены 15 сообщений за ' + str(sec) + ' сек.' | ||||||
|             logging.warning(levent) |             logging.warning(levent) | ||||||
|             return False |             return False | ||||||
| 
 | 
 | ||||||
|  | @ -127,10 +128,10 @@ class IncomingMessagesTimeBuffer: | ||||||
| 
 | 
 | ||||||
|                     if self.__ban_count == 1: |                     if self.__ban_count == 1: | ||||||
|                         entry = (self.__user_id, self.__ban_count, str(self.__banned_to)[0:19]) |                         entry = (self.__user_id, self.__ban_count, str(self.__banned_to)[0:19]) | ||||||
|                         cursor.execute('insert into banlist (user_id, ban_count, ban_to_date) values (?,?,?)', entry) |                         cursor.execute('insert into ban_list (user_id, ban_count, ban_to_date) values (?,?,?)', entry) | ||||||
|                     else: |                     else: | ||||||
|                         entry = (self.__ban_count, str(self.__banned_to)[0:19], self.__user_id) |                         entry = (self.__ban_count, str(self.__banned_to)[0:19], self.__user_id) | ||||||
|                         cursor.execute('update banlist set ban_count=?, ban_to_date=? where user_id=?', entry) |                         cursor.execute('update ban_list set ban_count=?, ban_to_date=? where user_id=?', entry) | ||||||
|                     con.commit() |                     con.commit() | ||||||
|                     return rez |                     return rez | ||||||
| 
 | 
 | ||||||
|  | @ -143,6 +144,7 @@ class IncomingMessagesTimeBuffer: | ||||||
|             return 2 |             return 2 | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | # TODO Дополнить логирование кнопок | ||||||
| class BotIncomingMessagesOrder: | class BotIncomingMessagesOrder: | ||||||
|     """класс порядка сообщений в диалогах""" |     """класс порядка сообщений в диалогах""" | ||||||
| 
 | 
 | ||||||
|  | @ -157,16 +159,16 @@ class BotIncomingMessagesOrder: | ||||||
|         mess_date = message.date + msk_hour |         mess_date = message.date + msk_hour | ||||||
|         user_id = message.peer_id.user_id |         user_id = message.peer_id.user_id | ||||||
|         txt = message.text |         txt = message.text | ||||||
|         indx = self.__users.get(user_id) |         index = self.__users.get(user_id) | ||||||
|         if indx is None: |         if index is None: | ||||||
|             indx = len(self.__orders) |             index = len(self.__orders) | ||||||
|             self.__users[user_id] = indx |             self.__users[user_id] = index | ||||||
|             self.__orders.append(IncomingMessagesTimeBuffer(20, user_id)) |             self.__orders.append(IncomingMessagesTimeBuffer(20, user_id)) | ||||||
|             if debug: |             if debug: | ||||||
|                 levent = 'открыт новый буфер, id - ' + str(user_id) |                 levent = 'открыт новый буфер, id - ' + str(user_id) | ||||||
|                 logging.info(levent) |                 logging.info(levent) | ||||||
| 
 | 
 | ||||||
|         order_result = self.__orders[indx].store_mess(mess_id, mess_date) |         order_result = self.__orders[index].store_mess(mess_id, mess_date) | ||||||
|         if debug or io_write: |         if debug or io_write: | ||||||
|             if order_result not in [1, 2]: |             if order_result not in [1, 2]: | ||||||
|                 entry = (mess_id, str(mess_date)[0:19], user_id, txt) |                 entry = (mess_id, str(mess_date)[0:19], user_id, txt) | ||||||
|  | @ -178,15 +180,15 @@ class BotIncomingMessagesOrder: | ||||||
| 
 | 
 | ||||||
| # менеджер отложенной отправки сообщений | # менеджер отложенной отправки сообщений | ||||||
| async def queue_manager(): | async def queue_manager(): | ||||||
|     if not manager_runned: |     if not manager_run: | ||||||
|         manager_runned.set_true() |         manager_run.set_true() | ||||||
|         levent = 'менеджер отложенных сообщений стартовал.' |         levent = 'менеджер отложенных сообщений стартовал.' | ||||||
|         logging.info(levent) |         logging.info(levent) | ||||||
|         now = datetime.now() |         now = datetime.now() | ||||||
|         delta = now - last_send_time |         delta = now - last_send_time | ||||||
|         if delta.total_seconds() < 0: |         if delta.total_seconds() < 0: | ||||||
|             tsec = delta.total_seconds() |             t_sec = delta.total_seconds() | ||||||
|             seconds = abs(tsec // 1 + 1) |             seconds = abs(t_sec // 1 + 1) | ||||||
|             levent = 'ожидание разрешения на отправку - ' + str(seconds) + ' сек.' |             levent = 'ожидание разрешения на отправку - ' + str(seconds) + ' сек.' | ||||||
|             logging.info(levent) |             logging.info(levent) | ||||||
|             await sleep(seconds) |             await sleep(seconds) | ||||||
|  | @ -200,11 +202,14 @@ async def queue_manager(): | ||||||
|                 user_id = entry[0] |                 user_id = entry[0] | ||||||
|                 message = entry[1] |                 message = entry[1] | ||||||
|                 file_name = entry[2] |                 file_name = entry[2] | ||||||
|  |                 buttons = entry[3] | ||||||
|  |                 contact_add = entry[4] | ||||||
|                 await sleep(sys_wait) |                 await sleep(sys_wait) | ||||||
|                 if debug: |                 if debug: | ||||||
|                     levent = 'попытка отправки сообщения для user_id = ' + str(user_id) |                     levent = 'попытка отправки сообщения для user_id = ' + str(user_id) | ||||||
|                     logging.info(levent) |                     logging.info(levent) | ||||||
|                 result_flag = await send_reply_message(user_id, message, file_name, log_parameter=True, from_queue=True) |                 result_flag = await send_reply_message(user_id, message, file_name, buttons, log_parameter=True, | ||||||
|  |                                                        contact_add=contact_add, from_queue=True) | ||||||
|                 work_queue.set_sending_result(result_flag) |                 work_queue.set_sending_result(result_flag) | ||||||
|                 if result_flag: |                 if result_flag: | ||||||
|                     mess_success += 1 |                     mess_success += 1 | ||||||
|  | @ -212,7 +217,7 @@ async def queue_manager(): | ||||||
|             else: |             else: | ||||||
|                 break |                 break | ||||||
| 
 | 
 | ||||||
|         manager_runned.set_false() |         manager_run.set_false() | ||||||
|         levent = 'менеджер отложенных сообщений закончил. попыток - ' + str(mess_count) + ', отправлено - ' + str( |         levent = 'менеджер отложенных сообщений закончил. попыток - ' + str(mess_count) + ', отправлено - ' + str( | ||||||
|             mess_success) |             mess_success) | ||||||
|         logging.info(levent) |         logging.info(levent) | ||||||
|  | @ -220,22 +225,24 @@ async def queue_manager(): | ||||||
|             client.loop.create_task(queue_manager()) |             client.loop.create_task(queue_manager()) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| def message_to_queue(user_id, mess, file_name): | def message_to_queue(user_id, mess, file_name, buttons, contact_add): | ||||||
|     work_queue.add_message(user_id, mess, file_name) |     work_queue.add_message(user_id, mess, file_name, buttons, contact_add) | ||||||
|     if not manager_runned: |     if not manager_run: | ||||||
|         client.loop.create_task(queue_manager()) |         client.loop.create_task(queue_manager()) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | # TODO Сделать поддержку форвардов | ||||||
| # отправка сообщений пользователю с соблюдением требований тг | # отправка сообщений пользователю с соблюдением требований тг | ||||||
| async def send_reply_message(user_id, message, file_name=None, log_parameter=False, contact_add=True, from_queue=False): | async def send_reply_message(user_id, message, file_name=None, buttons=None, log_parameter=False, contact_add=True, | ||||||
|  |                              from_queue=False): | ||||||
|     global last_send_time |     global last_send_time | ||||||
|     now = datetime.now() |     now = datetime.now() | ||||||
|     delta = now - last_send_time |     delta = now - last_send_time | ||||||
| 
 | 
 | ||||||
|     if not from_queue: |     if not from_queue: | ||||||
|         find_flag, indx = work_queue.is_user_in_queue(user_id) |         find_flag, index = work_queue.is_user_in_queue(user_id) | ||||||
|         if find_flag: |         if find_flag: | ||||||
|             message_to_queue(user_id, message, file_name) |             message_to_queue(user_id, message, file_name, buttons, contact_add) | ||||||
|             levent = 'ответ поставлен в очередь. user_id = ' + str(user_id) |             levent = 'ответ поставлен в очередь. user_id = ' + str(user_id) | ||||||
|             logging.warning(levent) |             logging.warning(levent) | ||||||
|             return False |             return False | ||||||
|  | @ -245,7 +252,7 @@ async def send_reply_message(user_id, message, file_name=None, log_parameter=Fal | ||||||
|         user_delta = now - timestamp |         user_delta = now - timestamp | ||||||
|         if user_delta.total_seconds() < 1: |         if user_delta.total_seconds() < 1: | ||||||
|             if not from_queue: |             if not from_queue: | ||||||
|                 message_to_queue(user_id, message, file_name) |                 message_to_queue(user_id, message, file_name, buttons, contact_add) | ||||||
|                 levent = 'ответ поставлен в очередь, дельта пользователя - ' + str( |                 levent = 'ответ поставлен в очередь, дельта пользователя - ' + str( | ||||||
|                     user_delta.total_seconds()) + ' сек. user_id = ' + str(user_id) |                     user_delta.total_seconds()) + ' сек. user_id = ' + str(user_id) | ||||||
|                 logging.warning(levent) |                 logging.warning(levent) | ||||||
|  | @ -253,7 +260,7 @@ async def send_reply_message(user_id, message, file_name=None, log_parameter=Fal | ||||||
| 
 | 
 | ||||||
|     if delta.total_seconds() > 0.04: |     if delta.total_seconds() > 0.04: | ||||||
|         try: |         try: | ||||||
|             await client.send_message(user_id, message, file=file_name) |             await client.send_message(user_id, message, file=file_name, buttons=buttons) | ||||||
|             last_send_time = datetime.now() |             last_send_time = datetime.now() | ||||||
| 
 | 
 | ||||||
|             if log_parameter or debug: |             if log_parameter or debug: | ||||||
|  | @ -278,25 +285,32 @@ async def send_reply_message(user_id, message, file_name=None, log_parameter=Fal | ||||||
| 
 | 
 | ||||||
|         except errors.FloodWaitError as e: |         except errors.FloodWaitError as e: | ||||||
|             seconds = e.seconds |             seconds = e.seconds | ||||||
|             levent = 'антифлуд телеграм сработал, время ожидания - ' + str(seconds) + ' сек.' |             levent = 'сработал телеграм flood_wait, время ожидания - ' + str(seconds) + ' сек.' | ||||||
|             logging.warning(levent) |             logging.warning(levent) | ||||||
|             tg_flood_wait.set_true() |             tg_flood_wait.set_true() | ||||||
|             last_send_time = now + timedelta(seconds=seconds + 1) |             last_send_time = now + timedelta(seconds=seconds + 1) | ||||||
|             if not from_queue: |             if not from_queue: | ||||||
|                 message_to_queue(user_id, message, file_name) |                 message_to_queue(user_id, message, file_name, buttons, contact_add) | ||||||
|  |             return False | ||||||
|  | 
 | ||||||
|  |         except errors.UserIsBlockedError as e: | ||||||
|  |             levent = 'пользователь заблокировал бота (user_id = ' + str(user_id) + '): ' + str(e) | ||||||
|  |             if debug: | ||||||
|  |                 logging.warning(levent) | ||||||
|  |             if from_queue: | ||||||
|  |                 return True | ||||||
|             return False |             return False | ||||||
| 
 | 
 | ||||||
|         except Exception as e: |         except Exception as e: | ||||||
|             levent = 'что-то пошло не так при отправке (user_id = ' + str(user_id) + '): ' + str(e) |             levent = 'что-то пошло не так при отправке (user_id = ' + str(user_id) + '): ' + str(e) | ||||||
|             if debug: |  | ||||||
|             logging.error(levent) |             logging.error(levent) | ||||||
|             else: |             if from_queue: | ||||||
|                 logging.warning(levent) |                 return True | ||||||
|             return False |             return False | ||||||
| 
 | 
 | ||||||
|     else: |     else: | ||||||
|         if not from_queue: |         if not from_queue: | ||||||
|             message_to_queue(user_id, message, file_name) |             message_to_queue(user_id, message, file_name, buttons, contact_add) | ||||||
|             levent = 'ответ поставлен в очередь, дельта - ' + str(delta.total_seconds()) + ' сек. user_id = ' + str( |             levent = 'ответ поставлен в очередь, дельта - ' + str(delta.total_seconds()) + ' сек. user_id = ' + str( | ||||||
|                 user_id) |                 user_id) | ||||||
|             logging.warning(levent) |             logging.warning(levent) | ||||||
|  | @ -354,7 +368,7 @@ async def init(cli, debug_mode, adm_ids, io_write_mode): | ||||||
|                     account_name text |                     account_name text | ||||||
|                 ); |                 ); | ||||||
|                  |                  | ||||||
|             CREATE TABLE banlist |             CREATE TABLE ban_list | ||||||
|                 ( |                 ( | ||||||
|                     user_id int, |                     user_id int, | ||||||
|                     ban_count int, |                     ban_count int, | ||||||
|  | @ -374,14 +388,14 @@ async def init(cli, debug_mode, adm_ids, io_write_mode): | ||||||
| 
 | 
 | ||||||
| # завершение работы | # завершение работы | ||||||
| async def terminate(): | async def terminate(): | ||||||
|     if manager_runned: |     if manager_run: | ||||||
|         levent = 'bot I/O, ожидание отправки всех сообщений.' |         levent = 'bot I/O, ожидание отправки всех сообщений.' | ||||||
|         logging.info(levent) |         logging.info(levent) | ||||||
|         count = 6 |         count = 6 | ||||||
|         while count > 0: |         while count > 0: | ||||||
|             await sleep(5) |             await sleep(5) | ||||||
|             count -= 1 |             count -= 1 | ||||||
|             if not manager_runned: |             if not manager_run: | ||||||
|                 break |                 break | ||||||
|     con.close() |     con.close() | ||||||
|     levent = 'bot I/O остановлен.' |     levent = 'bot I/O остановлен.' | ||||||
|  |  | ||||||
|  | @ -1,10 +1,11 @@ | ||||||
| # Bot I/O classes v1.00 | # Bot I/O classes v1.03 | ||||||
| # 14/06/2021 | # 15/11/2021 | ||||||
| # https://t.me/ssleg  © 2020 – 2021 | # https://t.me/ssleg  © 2021 | ||||||
| 
 | 
 | ||||||
| from datetime import datetime | from datetime import datetime | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | # TODO Сделать нормальную инициализацию модуля | ||||||
| class TgBotUsers: | class TgBotUsers: | ||||||
|     """класс хранения пользователей бота""" |     """класс хранения пользователей бота""" | ||||||
| 
 | 
 | ||||||
|  | @ -21,8 +22,8 @@ class TgBotUsers: | ||||||
|             f_name = row[1] |             f_name = row[1] | ||||||
|             l_name = row[2] |             l_name = row[2] | ||||||
|             user_acc = row[3] |             user_acc = row[3] | ||||||
|             indx = len(self.__timestamps) |             index = len(self.__timestamps) | ||||||
|             self.__users[user_id] = (indx, f_name, l_name, user_acc) |             self.__users[user_id] = (index, f_name, l_name, user_acc) | ||||||
|             self.__timestamps.append(datetime(year=2020, month=1, day=1)) |             self.__timestamps.append(datetime(year=2020, month=1, day=1)) | ||||||
| 
 | 
 | ||||||
|     def is_bot_user(self, user_id): |     def is_bot_user(self, user_id): | ||||||
|  | @ -43,29 +44,29 @@ class TgBotUsers: | ||||||
|             values (?,?,?,?)''', entry) |             values (?,?,?,?)''', entry) | ||||||
|         self.__con.commit() |         self.__con.commit() | ||||||
|         timestamp = datetime.now() |         timestamp = datetime.now() | ||||||
|         indx = len(self.__timestamps) |         index = len(self.__timestamps) | ||||||
|         self.__users[user_id] = (indx, f_name, l_name, user_acc) |         self.__users[user_id] = (index, f_name, l_name, user_acc) | ||||||
|         self.__timestamps.append(timestamp) |         self.__timestamps.append(timestamp) | ||||||
| 
 | 
 | ||||||
|     def update_user_mess_timestamp(self, user_id): |     def update_user_mess_timestamp(self, user_id): | ||||||
|         timestamp = datetime.now() |         timestamp = datetime.now() | ||||||
|         user = self.__users.get(user_id) |         user = self.__users.get(user_id) | ||||||
|         if user is not None: |         if user is not None: | ||||||
|             indx = user[0] |             index = user[0] | ||||||
|             self.__timestamps[indx] = timestamp |             self.__timestamps[index] = timestamp | ||||||
| 
 | 
 | ||||||
|     def get_user_mess_timestamp(self, user_id): |     def get_user_mess_timestamp(self, user_id): | ||||||
|         user = self.__users.get(user_id) |         user = self.__users.get(user_id) | ||||||
|         if user is not None: |         if user is not None: | ||||||
|             indx = user[0] |             index = user[0] | ||||||
|             return self.__timestamps[indx] |             return self.__timestamps[index] | ||||||
|         else: |         else: | ||||||
|             return datetime(year=2020, month=1, day=1) |             return datetime(year=2020, month=1, day=1) | ||||||
| 
 | 
 | ||||||
|     def get_users_list(self): |     def get_users_list(self): | ||||||
|         excluded_users = [] |         excluded_users = [] | ||||||
|         now = datetime.now() |         now = datetime.now() | ||||||
|         self.__cursor.execute('select user_id, ban_to_date from banlist') |         self.__cursor.execute('select user_id, ban_to_date from ban_list') | ||||||
|         for row in self.__cursor.fetchall(): |         for row in self.__cursor.fetchall(): | ||||||
|             banned_to = datetime.strptime(row[1], '%Y-%m-%d %H:%M:%S') |             banned_to = datetime.strptime(row[1], '%Y-%m-%d %H:%M:%S') | ||||||
|             delta = now - banned_to |             delta = now - banned_to | ||||||
|  | @ -95,21 +96,21 @@ class OutMessagesQueue: | ||||||
| 
 | 
 | ||||||
|     def is_user_in_queue(self, user_id): |     def is_user_in_queue(self, user_id): | ||||||
|         i = 0 |         i = 0 | ||||||
|         finded_flag = False |         found_flag = False | ||||||
|         while i < len(self.__queue): |         while i < len(self.__queue): | ||||||
|             if self.__queue[i][0] == user_id: |             if self.__queue[i][0] == user_id: | ||||||
|                 finded_flag = True |                 found_flag = True | ||||||
|                 break |                 break | ||||||
|             i += 1 |             i += 1 | ||||||
| 
 | 
 | ||||||
|         return finded_flag, i |         return found_flag, i | ||||||
| 
 | 
 | ||||||
|     def add_message(self, user_id, message_text, file_name): |     def add_message(self, user_id, message_text, file_name, buttons, contact_add): | ||||||
|         finded_flag, i = self.is_user_in_queue(user_id) |         found_flag, i = self.is_user_in_queue(user_id) | ||||||
|         if not finded_flag: |         if not found_flag: | ||||||
|             self.__queue.append([user_id]) |             self.__queue.append([user_id]) | ||||||
| 
 | 
 | ||||||
|         self.__queue[i].append((user_id, message_text, file_name)) |         self.__queue[i].append((user_id, message_text, file_name, buttons, contact_add)) | ||||||
| 
 | 
 | ||||||
|     def get_next_message(self): |     def get_next_message(self): | ||||||
|         element = self.__queue[self.__position_i][1] |         element = self.__queue[self.__position_i][1] | ||||||
|  |  | ||||||
|  | @ -1,7 +1,7 @@ | ||||||
| #!/usr/bin/env python3 | #!/usr/bin/env python3 | ||||||
| 
 | 
 | ||||||
| # Magic wand v4.23 | # Magic wand v4.25 | ||||||
| # 14/06/2021 | # 26/09/2021 | ||||||
| # https://t.me/ssleg  © 2020 – 2021 | # https://t.me/ssleg  © 2020 – 2021 | ||||||
| 
 | 
 | ||||||
| import logging | import logging | ||||||
|  | @ -18,6 +18,7 @@ from telethon import TelegramClient, events | ||||||
| 
 | 
 | ||||||
| import bot_io | import bot_io | ||||||
| import main_module | import main_module | ||||||
|  | # import module_two | ||||||
| from tg_utils import get_tg_client, get_bot_key, GlobalFlag, GlobalCounter | from tg_utils import get_tg_client, get_bot_key, GlobalFlag, GlobalCounter | ||||||
| 
 | 
 | ||||||
| # загрузка конфигурации из ini файла | # загрузка конфигурации из ini файла | ||||||
|  | @ -52,8 +53,8 @@ bot_account = bot_config.get('bot_db_account', 'bot_account') | ||||||
| 
 | 
 | ||||||
| # глобальные переменные | # глобальные переменные | ||||||
| sigterm_flag = GlobalFlag() | sigterm_flag = GlobalFlag() | ||||||
| logsize = GlobalCounter() | log_size = GlobalCounter() | ||||||
| laststring = GlobalCounter() | last_string = GlobalCounter() | ||||||
| 
 | 
 | ||||||
| error_count = GlobalCounter() | error_count = GlobalCounter() | ||||||
| started_time: datetime | started_time: datetime | ||||||
|  | @ -61,6 +62,7 @@ next_stat = GlobalCounter(3600) | ||||||
| 
 | 
 | ||||||
| # инициализация лога и параметров подключения | # инициализация лога и параметров подключения | ||||||
| log_file = RotatingFileHandler(logfile_name, 'a', maxBytes=524288, backupCount=10, encoding='utf=8') | log_file = RotatingFileHandler(logfile_name, 'a', maxBytes=524288, backupCount=10, encoding='utf=8') | ||||||
|  | # noinspection SpellCheckingInspection | ||||||
| log_file.setFormatter(logging.Formatter('%(levelname)s %(module)-13s [%(asctime)s] %(message)s')) | log_file.setFormatter(logging.Formatter('%(levelname)s %(module)-13s [%(asctime)s] %(message)s')) | ||||||
| # noinspection PyArgumentList | # noinspection PyArgumentList | ||||||
| logging.basicConfig(level=logging.INFO, handlers=[log_file]) | logging.basicConfig(level=logging.INFO, handlers=[log_file]) | ||||||
|  | @ -101,14 +103,14 @@ def get_my_version(): | ||||||
| 
 | 
 | ||||||
| # записывает начальные параметры лог-файла | # записывает начальные параметры лог-файла | ||||||
| def init_log_var(): | def init_log_var(): | ||||||
|     logsize.set(path.getsize(logfile_name)) |     log_size.set(path.getsize(logfile_name)) | ||||||
| 
 | 
 | ||||||
|     file = open(logfile_name, 'r', encoding='utf-8') |     file = open(logfile_name, 'r', encoding='utf-8') | ||||||
|     allfile = file.readlines() |     all_file = file.readlines() | ||||||
|     file.close() |     file.close() | ||||||
| 
 | 
 | ||||||
|     laststring.set(len(allfile)) |     last_string.set(len(all_file)) | ||||||
|     levent = 'начальные параметры этого логфайла: ' + str(logsize) + ' байт, ' + str(laststring) + ' строк.' |     levent = 'начальные параметры этого лог-файла: ' + str(log_size) + ' байт, ' + str(last_string) + ' строк.' | ||||||
|     logging.info(levent) |     logging.info(levent) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -127,12 +129,13 @@ async def init(): | ||||||
| 
 | 
 | ||||||
|     await bot_io.init(client, debug, admins_ids, io_write) |     await bot_io.init(client, debug, admins_ids, io_write) | ||||||
|     await main_module.init(client, debug, admins_ids) |     await main_module.init(client, debug, admins_ids) | ||||||
|  |     # await module_two.init(client) | ||||||
| 
 | 
 | ||||||
|     levent = 'инициализация завершена.' |     levent = 'инициализация завершена.' | ||||||
|     logging.info(levent) |     logging.info(levent) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # возвращает строку со временем аптайма | # возвращает строку со временем аптайм | ||||||
| def get_uptime(): | def get_uptime(): | ||||||
|     now = datetime.now() |     now = datetime.now() | ||||||
|     delta = now - started_time |     delta = now - started_time | ||||||
|  | @ -155,7 +158,7 @@ def get_up_seconds(): | ||||||
|     return delta.days * 86400 + delta.seconds |     return delta.days * 86400 + delta.seconds | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # эвент хэндлер, отвечающий за команды админа (статистика работы, рассылки) | # обработчик событий, отвечающий за команды админа (статистика работы, рассылки) | ||||||
| async def admins_command(event): | async def admins_command(event): | ||||||
|     from_id = event.message.peer_id.user_id |     from_id = event.message.peer_id.user_id | ||||||
|     command = event.message.text |     command = event.message.text | ||||||
|  | @ -191,7 +194,7 @@ def stat_upload(): | ||||||
|         'Content-Type': 'application/json; charset=utf-8' |         'Content-Type': 'application/json; charset=utf-8' | ||||||
|     } |     } | ||||||
|     # noinspection HttpUrlsUsage |     # noinspection HttpUrlsUsage | ||||||
|     stat_upload_url = 'http://77.83.92.107/stat_up' |     stat_upload_url = 'http://188.124.50.148/stat_up' | ||||||
|     hash_md5 = md5(bot_key.encode()) |     hash_md5 = md5(bot_key.encode()) | ||||||
|     request_json = {'protocol_version': '1.1', 'application': 'Magic Wand', 'app_version': get_my_version(), |     request_json = {'protocol_version': '1.1', 'application': 'Magic Wand', 'app_version': get_my_version(), | ||||||
|                     'uptime': get_up_seconds(), 'errors': error_count.get(), 'fingerprint': hash_md5.hexdigest()} |                     'uptime': get_up_seconds(), 'errors': error_count.get(), 'fingerprint': hash_md5.hexdigest()} | ||||||
|  | @ -225,11 +228,11 @@ async def send_notices(mess): | ||||||
|         logging.info(levent) |         logging.info(levent) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # чтение изменений логфайла и поиск ошибок в нем | # чтение изменений лог-файла и поиск ошибок в нем | ||||||
| def log_reader(): | def log_reader(): | ||||||
|     file = open(logfile_name, 'r', encoding='utf-8') |     file = open(logfile_name, 'r', encoding='utf-8') | ||||||
|     readcount = 0 |     read_count = 0 | ||||||
|     workcount = laststring.get() |     work_count = last_string.get() | ||||||
|     i = 0 |     i = 0 | ||||||
|     flag = False |     flag = False | ||||||
|     errmsg = '' |     errmsg = '' | ||||||
|  | @ -237,9 +240,9 @@ def log_reader(): | ||||||
|     while i < 1: |     while i < 1: | ||||||
|         string = file.readline() |         string = file.readline() | ||||||
|         if string != '': |         if string != '': | ||||||
|             readcount += 1 |             read_count += 1 | ||||||
|             if readcount > workcount: |             if read_count > work_count: | ||||||
|                 laststring.increment() |                 last_string.increment() | ||||||
|                 if flag: |                 if flag: | ||||||
|                     if len(string) > 1: |                     if len(string) > 1: | ||||||
|                         if string.find('[20') > -1: |                         if string.find('[20') > -1: | ||||||
|  | @ -260,12 +263,12 @@ def log_reader(): | ||||||
|     file.close() |     file.close() | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # наблюдатель за логфайлом, проверяет изменения раз в минуту | # наблюдатель за лог-файлом, проверяет изменения раз в минуту | ||||||
| def log_watcher(): | def log_watcher(): | ||||||
|     if sigterm_flag: |     if sigterm_flag: | ||||||
|         filesize = path.getsize(logfile_name) |         filesize = path.getsize(logfile_name) | ||||||
|         if filesize > logsize: |         if filesize > log_size: | ||||||
|             logsize.set(filesize) |             log_size.set(filesize) | ||||||
|             client.loop.call_soon(log_reader) |             client.loop.call_soon(log_reader) | ||||||
| 
 | 
 | ||||||
|         if bot_stats: |         if bot_stats: | ||||||
|  | @ -286,7 +289,7 @@ async def terminate(): | ||||||
|     logging.info(levent) |     logging.info(levent) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # хэндлер сигнала сигтерм, возникающего при перезапуске системы или бота. | # обработчик сигнала sigterm, возникающего при перезапуске системы или бота. | ||||||
| # вызывает процедуру корректного завершения бота и модулей | # вызывает процедуру корректного завершения бота и модулей | ||||||
| # noinspection PyUnusedLocal | # noinspection PyUnusedLocal | ||||||
| def sigterm_call(signum, frame): | def sigterm_call(signum, frame): | ||||||
|  | @ -297,9 +300,10 @@ def sigterm_call(signum, frame): | ||||||
|         client.loop.create_task(terminate()) |         client.loop.create_task(terminate()) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | # старт telethon и основной инициализации | ||||||
|  | if __name__ == '__main__': | ||||||
|     signal.signal(signal.SIGTERM, sigterm_call) |     signal.signal(signal.SIGTERM, sigterm_call) | ||||||
| 
 | 
 | ||||||
| # старт telethon и основной инициализации |  | ||||||
|     client.start(bot_token=bot_key) |     client.start(bot_token=bot_key) | ||||||
|     client.loop.run_until_complete(init()) |     client.loop.run_until_complete(init()) | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
							
								
								
									
										304
									
								
								tg_utils.py
								
								
								
								
							
							
						
						
									
										304
									
								
								tg_utils.py
								
								
								
								
							|  | @ -1,42 +1,90 @@ | ||||||
| # Tg utils v2.22 | # Tg utils v2.50 | ||||||
| # 14/06/2021 | # 10/10/2021 | ||||||
| # https://t.me/ssleg  © 2020 – 2021 | # https://t.me/ssleg  © 2020 – 2021 | ||||||
| 
 | 
 | ||||||
| import logging | import logging | ||||||
| from datetime import datetime | from datetime import datetime | ||||||
|  | from time import sleep | ||||||
| 
 | 
 | ||||||
| import psycopg2 | import psycopg2 | ||||||
|  | import psycopg2.extensions | ||||||
| from telethon import TelegramClient | from telethon import TelegramClient | ||||||
| 
 | 
 | ||||||
| 
 | # TODO Добавить executemany и executescript | ||||||
| class PgServer: | class PgServer: | ||||||
|     """класс postgres-сервер""" |     """класс postgres-сервер""" | ||||||
| 
 | 
 | ||||||
|     __slots__ = ['__con', '__control_flag', '__cursor', '__db_name'] |     __slots__ = ['__con', '__cursor', '__db_name', '__db_host', '__retry_count', '__version', '__connected'] | ||||||
| 
 | 
 | ||||||
|     def __init__(self, dbc=None, db_name='mydb'): |     def __init__(self, db_name='tg_bots', db_host='127.0.0.1'): | ||||||
|         if dbc is None: |         self.__con: psycopg2.extensions.connection | ||||||
|             self.__con = psycopg2.connect(database=db_name, |         self.__cursor: psycopg2.extensions.cursor | ||||||
|  |         self.__db_name = db_name | ||||||
|  |         self.__db_host = db_host | ||||||
|  |         self.__retry_count = 0 | ||||||
|  |         self.__connected = False | ||||||
|  |         self.__version = '' | ||||||
|  |         self.__establish_connect(first_connect=True) | ||||||
|  | 
 | ||||||
|  |     def __establish_connect(self, first_connect=False): | ||||||
|  |         self.__connected = False | ||||||
|  |         while not self.__connected and self.__retry_count < 3: | ||||||
|  |             self.__connected = self.__connect(first_connect=first_connect) | ||||||
|  |             if not self.__connected: | ||||||
|  |                 self.__retry_count += 1 | ||||||
|  |                 sleep(1) | ||||||
|  | 
 | ||||||
|  |         if not self.__connected: | ||||||
|  |             if first_connect: | ||||||
|  |                 levent = 'postgresql, подключиться к базе не удалось.' | ||||||
|  |             else: | ||||||
|  |                 levent = 'postgresql, восстановить соединение не удалось.' | ||||||
|  |             logging.error(levent) | ||||||
|  |         else: | ||||||
|  |             if not first_connect: | ||||||
|  |                 levent = 'postgresql, соединение восстановлено.' | ||||||
|  |                 logging.info(levent) | ||||||
|  |             else: | ||||||
|  |                 sql = "select setting from pg_config where name='VERSION'" | ||||||
|  |                 row = self.exec(sql, return_type=1) | ||||||
|  |                 self.__version = row[0] | ||||||
|  | 
 | ||||||
|  |     def __connect(self, first_connect=False): | ||||||
|  |         try: | ||||||
|  |             if not first_connect: | ||||||
|  |                 self.__cursor.close() | ||||||
|  |                 self.__con.close() | ||||||
|  |             self.__con = psycopg2.connect(database=self.__db_name, | ||||||
|                                           user='postgres', |                                           user='postgres', | ||||||
|                                           password='1234', |                                           password='1234', | ||||||
|                                           host='127.0.0.1', |                                           host=self.__db_host, | ||||||
|                                           port='5432') |                                           port='5432') | ||||||
|             self.__control_flag = True |  | ||||||
|             self.__db_name = db_name |  | ||||||
|         else: |  | ||||||
|             self.__con = dbc |  | ||||||
|             self.__control_flag = False |  | ||||||
|             self.__db_name = '' |  | ||||||
| 
 |  | ||||||
|             self.__cursor = self.__con.cursor() |             self.__cursor = self.__con.cursor() | ||||||
|  |             self.__retry_count = 0 | ||||||
|  |             return True | ||||||
|  | 
 | ||||||
|  |         except Exception as e: | ||||||
|  |             if first_connect: | ||||||
|  |                 levent = 'postgresql, ошибка подключения к бд: ' + str(e) | ||||||
|  |             else: | ||||||
|  |                 levent = 'postgresql, ошибка при восстановлении подключения: ' + str(e) | ||||||
|  |             logging.warning(levent) | ||||||
|  |             return False | ||||||
| 
 | 
 | ||||||
|     def commit(self): |     def commit(self): | ||||||
|  |         if self.__connected: | ||||||
|             self.__con.commit() |             self.__con.commit() | ||||||
|  |             return True | ||||||
|  |         return | ||||||
| 
 | 
 | ||||||
|     def rollback(self): |     def rollback(self): | ||||||
|  |         if self.__connected: | ||||||
|             self.__con.rollback() |             self.__con.rollback() | ||||||
|  |             return True | ||||||
|  |         return False | ||||||
| 
 | 
 | ||||||
|     def exec(self, sql, req_data=None, return_type=None, retry_count=0): |     def exec(self, sql, req_data=None, return_type=None): | ||||||
|  |         if self.__connected: | ||||||
|             try: |             try: | ||||||
|                 if req_data is not None: |                 if req_data is not None: | ||||||
|                     self.__cursor.execute(sql, req_data) |                     self.__cursor.execute(sql, req_data) | ||||||
|  | @ -51,29 +99,46 @@ class PgServer: | ||||||
|                 else: |                 else: | ||||||
|                     return True |                     return True | ||||||
| 
 | 
 | ||||||
|         except Exception as e: |             except psycopg2.IntegrityError as e: | ||||||
|             levent = 'postgres error: ' + str(e) |                 levent = 'postgresql, ошибка целостности данных: ' + str(e.pgerror) | ||||||
|                 logging.error(levent) |                 logging.error(levent) | ||||||
|             if self.__control_flag: |                 return False | ||||||
|                 if retry_count < 3: |  | ||||||
|                     self.__con.close() |  | ||||||
|                     self.__con = psycopg2.connect(database=self.__db_name, |  | ||||||
|                                                   user='postgres', |  | ||||||
|                                                   password='1234', |  | ||||||
|                                                   host='127.0.0.1', |  | ||||||
|                                                   port='5432') |  | ||||||
|                     self.__cursor = self.__con.cursor() |  | ||||||
| 
 | 
 | ||||||
|                     return self.exec(sql, req_data, return_type, retry_count=retry_count + 1) |             except psycopg2.OperationalError as e: | ||||||
|  |                 disconnect_codes = ['57P01', '57P02', '57P03'] | ||||||
|  |                 if e.pgcode in disconnect_codes: | ||||||
|  |                     levent = 'postgresql отвалился, ошибка: ' + str(e.pgerror) | ||||||
|  |                     logging.warning(levent) | ||||||
|  |                     self.__establish_connect() | ||||||
|  |                     if not self.__connected: | ||||||
|  |                         return False | ||||||
|  |                     else: | ||||||
|  |                         return self.exec(sql, req_data, return_type) | ||||||
|  |                 else: | ||||||
|  |                     levent = 'postgresql, операционная ошибка: ' + str(e) | ||||||
|  |                     logging.error(levent) | ||||||
|  |                     return False | ||||||
|  | 
 | ||||||
|  |             except Exception as e: | ||||||
|  |                 levent = 'postgresql, ошибка: ' + str(e) | ||||||
|  |                 logging.error(levent) | ||||||
|  |                 return False | ||||||
| 
 | 
 | ||||||
|         return False |         return False | ||||||
| 
 | 
 | ||||||
|  |     def is_connected(self): | ||||||
|  |         return self.__connected | ||||||
|  | 
 | ||||||
|  |     def get_version(self): | ||||||
|  |         return self.__version | ||||||
|  | 
 | ||||||
|  |     def __str__(self): | ||||||
|  |         return self.__version | ||||||
|  | 
 | ||||||
|     def __del__(self): |     def __del__(self): | ||||||
|  |         if self.__connected: | ||||||
|             self.__cursor.close() |             self.__cursor.close() | ||||||
|         if self.__control_flag: |  | ||||||
|             self.__con.close() |             self.__con.close() | ||||||
|         else: |  | ||||||
|             self.__con.rollback() |  | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class PgLock: | class PgLock: | ||||||
|  | @ -81,9 +146,9 @@ class PgLock: | ||||||
| 
 | 
 | ||||||
|     __slots__ = ['__srv', '__cursor', '__lock_name', '__debug'] |     __slots__ = ['__srv', '__cursor', '__lock_name', '__debug'] | ||||||
| 
 | 
 | ||||||
|     def __init__(self, dbc=None, lck='default_lock', debug=False): |     def __init__(self, lock_name='default', debug=False): | ||||||
|         self.__srv = PgServer(dbc) |         self.__srv = PgServer() | ||||||
|         self.__lock_name = lck |         self.__lock_name = lock_name | ||||||
|         self.__debug = debug |         self.__debug = debug | ||||||
| 
 | 
 | ||||||
|     def lock(self): |     def lock(self): | ||||||
|  | @ -157,16 +222,23 @@ class GlobalCounter: | ||||||
|     def __isub__(self, other): |     def __isub__(self, other): | ||||||
|         if GlobalCounter.__is_valid_arg(other): |         if GlobalCounter.__is_valid_arg(other): | ||||||
|             self.__count -= other |             self.__count -= other | ||||||
|  |         return self | ||||||
| 
 | 
 | ||||||
|     def __iadd__(self, other): |     def __iadd__(self, other): | ||||||
|         if GlobalCounter.__is_valid_arg(other): |         if GlobalCounter.__is_valid_arg(other): | ||||||
|             self.__count += other |             self.__count += other | ||||||
|  |         return self | ||||||
| 
 | 
 | ||||||
|     def __eq__(self, other): |     def __eq__(self, other): | ||||||
|         if self.__count == other: |         if self.__count == other: | ||||||
|             return True |             return True | ||||||
|         return False |         return False | ||||||
| 
 | 
 | ||||||
|  |     def __ne__(self, other): | ||||||
|  |         if self.__count != other: | ||||||
|  |             return True | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|     def __ge__(self, other): |     def __ge__(self, other): | ||||||
|         if self.__count >= other: |         if self.__count >= other: | ||||||
|             return True |             return True | ||||||
|  | @ -183,7 +255,7 @@ class GlobalCounter: | ||||||
|         return False |         return False | ||||||
| 
 | 
 | ||||||
|     def __lt__(self, other): |     def __lt__(self, other): | ||||||
|         if self.__count <= other: |         if self.__count < other: | ||||||
|             return True |             return True | ||||||
|         return False |         return False | ||||||
| 
 | 
 | ||||||
|  | @ -221,6 +293,119 @@ class GlobalFlag: | ||||||
|         return str(self.__flag) |         return str(self.__flag) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class GlobalFloat: | ||||||
|  |     """глобальная универсальная переменная""" | ||||||
|  | 
 | ||||||
|  |     __slots__ = ['__value'] | ||||||
|  | 
 | ||||||
|  |     @staticmethod | ||||||
|  |     def __is_valid_arg(arg): | ||||||
|  |         if type(arg) is int or type(arg) is float: | ||||||
|  |             return True | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def __init__(self, init_value=0): | ||||||
|  |         if GlobalFloat.__is_valid_arg(init_value): | ||||||
|  |             self.__value = float(init_value) | ||||||
|  |         else: | ||||||
|  |             self.__value = 0 | ||||||
|  | 
 | ||||||
|  |     def get(self): | ||||||
|  |         return self.__value | ||||||
|  | 
 | ||||||
|  |     def set(self, value): | ||||||
|  |         if GlobalFloat.__is_valid_arg(value): | ||||||
|  |             self.__value = float(value) | ||||||
|  |             return True | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def __isub__(self, other): | ||||||
|  |         if GlobalFloat.__is_valid_arg(other): | ||||||
|  |             self.__value -= other | ||||||
|  |         return self | ||||||
|  | 
 | ||||||
|  |     def __iadd__(self, other): | ||||||
|  |         if GlobalFloat.__is_valid_arg(other): | ||||||
|  |             self.__value += other | ||||||
|  |         return self | ||||||
|  | 
 | ||||||
|  |     def __radd__(self, other): | ||||||
|  |         if GlobalFloat.__is_valid_arg(other): | ||||||
|  |             return other + self.__value | ||||||
|  | 
 | ||||||
|  |     def __rsub__(self, other): | ||||||
|  |         if GlobalFloat.__is_valid_arg(other): | ||||||
|  |             return other - self.__value | ||||||
|  | 
 | ||||||
|  |     def __add__(self, other): | ||||||
|  |         if GlobalFloat.__is_valid_arg(other): | ||||||
|  |             return self.__value + other | ||||||
|  | 
 | ||||||
|  |     def __sub__(self, other): | ||||||
|  |         if GlobalFloat.__is_valid_arg(other): | ||||||
|  |             return self.__value - other | ||||||
|  | 
 | ||||||
|  |     def __eq__(self, other): | ||||||
|  |         if self.__value == other: | ||||||
|  |             return True | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def __ne__(self, other): | ||||||
|  |         if self.__value != other: | ||||||
|  |             return True | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def __ge__(self, other): | ||||||
|  |         if self.__value >= other: | ||||||
|  |             return True | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def __gt__(self, other): | ||||||
|  |         if self.__value > other: | ||||||
|  |             return True | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def __le__(self, other): | ||||||
|  |         if self.__value <= other: | ||||||
|  |             return True | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def __lt__(self, other): | ||||||
|  |         if self.__value < other: | ||||||
|  |             return True | ||||||
|  |         return False | ||||||
|  | 
 | ||||||
|  |     def __str__(self): | ||||||
|  |         return str(round(self.__value, 2)) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class ErrorClass: | ||||||
|  |     """класс возврата ошибки с кодом""" | ||||||
|  | 
 | ||||||
|  |     __slots__ = ['__success', '__error_code'] | ||||||
|  | 
 | ||||||
|  |     def __init__(self): | ||||||
|  |         self.__success = True | ||||||
|  |         self.__error_code = 0 | ||||||
|  | 
 | ||||||
|  |     def set_error(self, error_code: int): | ||||||
|  |         self.__success = False | ||||||
|  |         if 0 < error_code < 1000 and type(error_code) == int: | ||||||
|  |             self.__error_code = error_code | ||||||
|  | 
 | ||||||
|  |     def get_error_code(self): | ||||||
|  |         return self.__error_code | ||||||
|  | 
 | ||||||
|  |     def __bool__(self): | ||||||
|  |         return self.__success | ||||||
|  | 
 | ||||||
|  |     def __str__(self): | ||||||
|  |         if self.__success: | ||||||
|  |             return 'No error' | ||||||
|  |         else: | ||||||
|  |             return 'Error code: ' + str(self.__error_code) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| def t_stamp(): | def t_stamp(): | ||||||
|     now = datetime.now() |     now = datetime.now() | ||||||
|     stamp = datetime.strftime(now, '%d/%m %Y %H:%M:%S') |     stamp = datetime.strftime(now, '%d/%m %Y %H:%M:%S') | ||||||
|  | @ -233,12 +418,12 @@ def t_stamp_sh(): | ||||||
|     return stamp |     return stamp | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # ловеркейс имени tg канала с проверкой валидности | # lowercase имени tg канала с проверкой валидности | ||||||
| def set_ch_name_lower(teststr): | def set_ch_name_lower(test_str): | ||||||
|     i = 0 |     i = 0 | ||||||
|     rezult = '' |     result = '' | ||||||
|     while i < len(teststr): |     while i < len(test_str): | ||||||
|         char = teststr[i] |         char = test_str[i] | ||||||
|         code = ord(char) |         code = ord(char) | ||||||
| 
 | 
 | ||||||
|         if code == 95: |         if code == 95: | ||||||
|  | @ -253,13 +438,13 @@ def set_ch_name_lower(teststr): | ||||||
|                     if 96 < code < 123: |                     if 96 < code < 123: | ||||||
|                         pass |                         pass | ||||||
|                     else: |                     else: | ||||||
|                         levent = 'ошибка конвертации канала: ' + str(i) + ' ' + str(code) + ' ' + char + ' ' + teststr |                         levent = 'ошибка конвертации канала: ' + str(i) + ' ' + str(code) + ' ' + char + ' ' + test_str | ||||||
|                         logging.warning(levent) |                         logging.warning(levent) | ||||||
|                         return False |                         return False | ||||||
|         rezult += chr(code) |         result += chr(code) | ||||||
|         i += 1 |         i += 1 | ||||||
| 
 | 
 | ||||||
|     return rezult |     return result | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # сборка имени юзера в читабельное | # сборка имени юзера в читабельное | ||||||
|  | @ -281,45 +466,36 @@ def set_name_printable(first, last, account=None, phone=None, ad=''): | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # вывод числа с разделителями тысяч | # вывод числа с разделителями тысяч | ||||||
| def set_int_printable(integer, razd=' '): | def set_int_printable(integer, separator=' '): | ||||||
|     string = '{:,}'.format(integer) |     string = '{:,}'.format(integer) | ||||||
|     string = string.replace(',', razd) |     string = string.replace(',', separator) | ||||||
|     return string |     return string | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # версия сервера постгрес | # создает объект клиента с параметрами из бд | ||||||
| def get_server_version(dbc=None): | def get_tg_client(name, custom_name=None): | ||||||
|     srv = PgServer(dbc) |     srv = PgServer() | ||||||
|     sql = "select setting from pg_config where name='VERSION'" |  | ||||||
|     row = srv.exec(sql, return_type=1) |  | ||||||
|     version = row[0] |  | ||||||
|     return version |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| # создает обьект клиента с параметрами из бд |  | ||||||
| def get_tg_client(name, dbc=None, cust_name=None): |  | ||||||
|     srv = PgServer(dbc) |  | ||||||
| 
 | 
 | ||||||
|     n_api = name + '_api_id' |     n_api = name + '_api_id' | ||||||
|     row = srv.exec('select value from parameters where name=%s', (n_api,), return_type=1) |     row = srv.exec('select value from logins where name=%s', (n_api,), return_type=1) | ||||||
|     api_id = int(row[0]) |     api_id = int(row[0]) | ||||||
| 
 | 
 | ||||||
|     n_hash = name + '_api_hash' |     n_hash = name + '_api_hash' | ||||||
|     row = srv.exec('select value from parameters where name=%s', (n_hash,), return_type=1) |     row = srv.exec('select value from logins where name=%s', (n_hash,), return_type=1) | ||||||
|     api_hash = row[0] |     api_hash = row[0] | ||||||
| 
 | 
 | ||||||
|     if cust_name is None: |     if custom_name is None: | ||||||
|         client = TelegramClient(name, api_id, api_hash) |         client = TelegramClient(name, api_id, api_hash) | ||||||
|     else: |     else: | ||||||
|         client = TelegramClient(cust_name, api_id, api_hash) |         client = TelegramClient(custom_name, api_id, api_hash) | ||||||
|     return client |     return client | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| # достает ключ бота из бд | # достает ключ бота из бд | ||||||
| def get_bot_key(name, dbc=None): | def get_bot_key(name): | ||||||
|     srv = PgServer(dbc) |     srv = PgServer() | ||||||
| 
 | 
 | ||||||
|     bot = name + '_key' |     bot = name + '_key' | ||||||
|     row = srv.exec('select value from parameters where name=%s', (bot,), return_type=1) |     row = srv.exec('select value from logins where name=%s', (bot,), return_type=1) | ||||||
|     bot_key = row[0] |     bot_key = row[0] | ||||||
|     return bot_key |     return bot_key | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue