async def send_message(self, to_id): message_text = self.aa_options['message'] message = message_text.replace( '[username]', self.tg_bot_controller.tg_client.me_user_name) if message.find('[statistics]') >= 0: stats_str = await self.tg_bot_controller.tg_client.status_controller.get_user_aa_statistics_text( self.tg_bot_controller.tg_client.me_user_id) message = message.replace('[statistics]', '\n' + stats_str) if self.aa_options['show_bot']: message = self.tg_bot_controller.text_to_bot_text( message, to_id, "dialog") else: message = self.tg_bot_controller.text_to_bot_text( message, to_id, "bot") to_username = await self.tg_bot_controller.tg_client.get_entity_name( to_id, 'User') msg_log = StatusController.datetime_to_str(datetime.now( )) + ' Sending AA message to user "' + to_username + '"' msg_log = msg_log + '\n' + '<<< ' + message print(msg_log) await self.tg_bot_controller.tg_client.send_message( PeerUser(to_id), message) if self.aa_options['notify_entity_id']: msg_log = StatusController.datetime_to_str(datetime.now( )) + ' Отправляем сообщение пользователю {}'.format( await self.tg_bot_controller.user_link(to_id, to_username)) msg_log = msg_log + '\n\n' + '``` ' + message + '```' await self.send_message_to_user( self.aa_options['notify_entity_id'], msg_log, do_set_next=False)
async def cmd_plot_week(self, from_id, params): to_id = from_id from_id = await self.tg_bot_controller.get_from_id_param( from_id, params) date_str1 = StatusController.datetime_to_str( datetime.now() + timedelta(days=-6), '%Y-%m-%d') date_str2 = StatusController.datetime_to_str( datetime.now() + timedelta(days=1), '%Y-%m-%d') await self.send_activity_message( from_id, to_id, (date_str1, date_str2), img_caption="График активности [user] за неделю")
async def on_user_message_to_me(self, from_id, message_text): if not self.aa_options['is_set']: return if from_id in self.aa_not_for_users: return if (from_id in self.aa_for_users) and self.aa_for_users[from_id]: return try: entity = await self.tg_bot_controller.tg_client.get_entity( PeerUser(int(from_id))) except: return if (not entity) or (type(entity) != User): return user_level = self.tg_bot_controller.get_entity_rights_level( entity, self.aa_options['from_user_ids']) if user_level < self.aa_options['from_mode']: if from_id not in self.aa_not_for_users: self.aa_not_for_users.append(from_id) return self.aa_for_users[from_id] = StatusController.now_local_datetime() check_user_name = await self.tg_bot_controller.tg_client.get_entity_name( from_id, 'User') print( StatusController.datetime_to_str(datetime.now()) + ' Adding AA schedule for user "' + check_user_name + '"') if self.aa_options['answer_after_minutes'] <= 0.05: await self.do_on_timer([from_id])
async def show_current_branch_commands(self, from_id, pre_text=None): if self.aa_options['is_set']: msg = 'Автоответчик для ' + self.tg_bot_controller.tg_client.me_user_name + ' настроен и запущен!\n\nПараметры:\n' msg = msg + '```' for k, v in self.aa_options.items(): if k not in ['is_set', 'notify_entity_id']: msg = msg + k + ' = ' + str(v) + '\n' msg = msg + '```\n' msg = msg + 'Пользователи: ' if len(self.aa_for_users) > 0: for user_id, user_date in self.aa_for_users.items(): msg = msg + '\n' msg = msg + (await self.tg_bot_controller.user_link(user_id)) msg = msg + ' **---** ' if user_date: msg = msg + 'Ждёт с ' + StatusController.datetime_to_str( user_date) else: msg = msg + 'Сообщение отправлено' else: msg = msg + 'Отсутствуют' msg = msg + '\n' else: msg = '' msg_text = msg + "\n".join(await self.get_commands_description_list( from_id, pre_text)) buttons = await self.get_commands_buttons_list(from_id) await self.send_message_to_user(from_id, msg_text.strip(), buttons=buttons, set_active=True)
def add_entity_db_name(self, entity_id, entity_type, entity_name, entity_phone=None, entity_is_megagroup=False): row = self.db_conn.execute( """ SELECT * FROM `entities` WHERE `entity_id` = ? ORDER BY `version` DESC LIMIT 1 """, [str(entity_id)]).fetchone() if row: if (entity_name == row['entity_name']) and (entity_type == row['entity_type']): return None version = int(row['version']) + 1 else: version = 1 if entity_is_megagroup: entity_type = 'Megagroup' c = self.db_conn.cursor() c.execute('INSERT INTO `entities` VALUES(?, ?, ?, ?, ?, ?, ?, ?)', [ str(entity_id), str(entity_type), entity_name, entity_phone, StatusController.datetime_to_str(datetime.now()), None, None, str(version) ]) self.db_conn.commit()
async def on_me_write_message_to_user(self, to_user_id): if not self.aa_options['is_set']: return if (to_user_id in self.aa_for_users) and self.aa_for_users[to_user_id]: del self.aa_for_users[to_user_id] check_user_name = await self.tg_bot_controller.tg_client.get_entity_name( to_user_id, 'User') print( StatusController.datetime_to_str(datetime.now()) + ' Removing AA schedule for user "' + check_user_name + '"')
async def cmd_plot_today(self, from_id, params): to_id = from_id from_id = await self.tg_bot_controller.get_from_id_param( from_id, params) now_str = StatusController.datetime_to_str(datetime.now(), '%Y-%m-%d') await self.send_activity_message( from_id, to_id, now_str, img_caption="График активности [user] за сегодня")
def find_message_by_id_date(self, from_id, date): date = StatusController.tg_datetime_to_local_datetime(date) date = StatusController.datetime_to_str(date, '%Y-%m-%d %H:%M:%S') res = self.db_conn.execute( """ SELECT m.*, (SELECT version FROM `messages` m1 WHERE m1.`entity_id` = m.`entity_id` AND m1.message_id = m.message_id AND m1.from_id = m.from_id ORDER BY version DESC LIMIT 1) as 'max_version', (SELECT removed FROM `messages` m1 WHERE m1.`entity_id` = m.`entity_id` AND m1.message_id = m.message_id AND m1.from_id = m.from_id ORDER BY version DESC LIMIT 1) as 'is_removed' FROM `messages` m WHERE m.`from_id` = ? AND m.`taken_at` LIKE ? ORDER BY m.`taken_at` ASC LIMIT 1 """, [str(from_id), date + '%'] ) row = res.fetchone() return row
async def show_message_edits(self, from_id, entity_id, message_id): message_edits = self.dialog_stats.get_message_edits( entity_id, message_id) results = [ 'Кажется, ты переслал сообщение из отслеживаемого диалога', 'Выведем доп. информацию по нему...', 'Число правок: {}'.format(len(message_edits) - 1) ] if len(message_edits) > 0: last_version = None for message_edit in message_edits: results.append('') results.append('**Версия {} / {}**'.format( message_edit['version'], message_edit['max_version'])) date = StatusController.datetime_from_str( message_edit['taken_at'], '%Y-%m-%d %H:%M:%S%z') results.append('Дата: {}'.format( StatusController.datetime_to_str(date))) results.append('Сообщение: \n[{}]\n'.format( self.dialog_stats.remove_message_tags( message_edit['message']))) if last_version: edit_ratio = self.dialog_stats.get_str_difference_ratio( self.dialog_stats.remove_message_tags( last_version['message']), self.dialog_stats.remove_message_tags( message_edit['message'])) results.append('Процент правок: {0:0.2f}%'.format( 100 * edit_ratio)) diff_counts = self.dialog_stats.get_str_difference_counts( last_version['message'], message_edit['message']) results.append('Число замен : {}'.format( diff_counts['replaces_count_edit'])) results.append('Число вставок : {}'.format( diff_counts['inserts_count_edit'])) results.append('Число удалений: {}'.format( diff_counts['deletes_count_edit'])) last_version = message_edit results = "\n".join(results) await self.send_message_to_user(from_id, results)
async def do_on_timer(self, check_ids=None): try: if not self.aa_options['is_set']: return if ((datetime.now() - self.tg_bot_controller.tg_client. me_last_activity).total_seconds() / 60.0) < self.aa_options['activate_after_minutes']: return if not check_ids: check_ids = list(self.aa_for_users.keys()) dialogs = None for check_id in check_ids: if (check_id in self.aa_for_users) and self.aa_for_users[check_id]: if ((StatusController.now_local_datetime() - self.aa_for_users[check_id]).total_seconds() / 60.0) >= self.aa_options['answer_after_minutes']: if not dialogs: input_peer = await self.tg_bot_controller.tg_client.get_input_entity( PeerUser(check_id)) dialogs = await self.tg_bot_controller.tg_client( GetDialogsRequest(limit=0, offset_date=None, offset_id=0, offset_peer=input_peer, hash=0, folder_id=0)) if type(dialogs) == DialogsSlice: dialogs = dialogs.dialogs c_dialog = None if dialogs: for dialog in dialogs: if (type(dialog.peer) == PeerUser) and ( dialog.peer.user_id == check_id) and ( dialog.read_inbox_max_id > 0): c_dialog = dialog break do_remove_aa_user_record = False if (not c_dialog) or (c_dialog.unread_count > 0): unread_cnt_not_me = 0 t_messages = await self.tg_bot_controller.tg_client.get_messages( PeerUser(check_id), limit=10) for t_message in t_messages: message_date = StatusController.tg_datetime_to_local_datetime( t_message.date) user_date = self.aa_for_users[check_id] if t_message.from_id == self.tg_bot_controller.tg_client.me_user_id: if (message_date > user_date) and ( (message_date - user_date).total_seconds() > 1): do_remove_aa_user_record = True break elif c_dialog and (t_message.id > c_dialog.read_inbox_max_id): unread_cnt_not_me = unread_cnt_not_me + 1 if c_dialog and (unread_cnt_not_me == 0): do_remove_aa_user_record = True elif c_dialog and (c_dialog.unread_count == 0): do_remove_aa_user_record = True if do_remove_aa_user_record: del self.aa_for_users[check_id] check_user_name = await self.tg_bot_controller.tg_client.get_entity_name( check_id, 'User') print( StatusController.datetime_to_str( datetime.now()) + ' Removing AA schedule for user "' + check_user_name + '"') continue self.aa_for_users[check_id] = None self.aa_not_for_users.append(check_id) await self.send_message(check_id) if self.aa_options['allow_bot_chat']: await self.tg_bot_controller.init_chat_for_user( check_id, check_id, False, self.aa_options['show_bot']) except: traceback.print_exc()
async def get_me_dialog_statistics(self, user_id, date_from=None, title='за всё время', only_last_dialog=False, skip_vocab=False): new_normal_form_cache = CacheHelper().get_from_cache('normal_forms', 'dialog_stats', False) if new_normal_form_cache: self.normal_form_cache = new_normal_form_cache new_word_type_form_cache = CacheHelper().get_from_cache('word_type_forms', 'dialog_stats', False) if new_word_type_form_cache: self.word_type_form_cache = new_word_type_form_cache days_a = '?' if (not date_from) and (not only_last_dialog): res = self.db_conn.execute( """ SELECT * FROM `activity` ORDER BY taken_at ASC """, []) rows = list(res.fetchall()) days_a = 1 if len(rows) > 1: date1 = StatusController.datetime_from_str(rows[0]['taken_at']) date2 = StatusController.datetime_from_str(rows[len(rows) - 1]['taken_at']) days_a = round((date2 - date1).total_seconds() / (24 * 60 * 60)) results = [] last_dialogue_date = None try: user_entity = await self.tg_client.get_entity(PeerUser(user_id)) except: user_entity = None if user_entity and (type(user_entity) == User): if not date_from: res = self.db_conn.execute( """ SELECT m.*, (SELECT version FROM `messages` m1 WHERE m1.`entity_id` = m.`entity_id` AND m1.message_id = m.message_id AND m1.from_id = m.from_id ORDER BY version DESC LIMIT 1) as 'max_version', (SELECT removed FROM `messages` m1 WHERE m1.`entity_id` = m.`entity_id` AND m1.message_id = m.message_id AND m1.from_id = m.from_id ORDER BY version DESC LIMIT 1) as 'is_removed' FROM `messages` m WHERE m.`entity_id` = ? OR m.`entity_id` = ? ORDER BY m.`taken_at` ASC, m.`message_id` ASC, m.`version` ASC """, [str(user_id), str(self.tg_client.me_user_id)] ) else: date_from = StatusController.datetime_to_str(date_from, '%Y-%m-%d') res = self.db_conn.execute( """ SELECT m.*, (SELECT version FROM `messages` m1 WHERE m1.`entity_id` = m.`entity_id` AND m1.message_id = m.message_id AND m1.from_id = m.from_id ORDER BY version DESC LIMIT 1) as 'max_version', (SELECT removed FROM `messages` m1 WHERE m1.`entity_id` = m.`entity_id` AND m1.message_id = m.message_id AND m1.from_id = m.from_id ORDER BY version DESC LIMIT 1) as 'is_removed' FROM `messages` m WHERE (m.`entity_id` = ? OR m.`entity_id` = ?) AND (m.`taken_at` > ?) ORDER BY m.`taken_at` ASC, m.`message_id` ASC, m.`version` ASC """, [str(user_id), str(self.tg_client.me_user_id), date_from] ) rows = list(res.fetchall()) me_name = self.tg_client.me_user_entity_name another_name = await self.tg_client.get_entity_name(user_id, 'User') dialog_name = me_name + ' <-> ' + another_name results.append('**Диалог '+dialog_name+' ('+title+')'+':**') results.append('') results.append('Сообщений диалога в БД: ' + str(len(rows))) if len(rows) > 0: date_start = StatusController.datetime_from_str(rows[0]['taken_at'], '%Y-%m-%d %H:%M:%S%z') if not only_last_dialog: results.append('Самое раннее сообщение диалога в БД: ' + StatusController.datetime_to_str(date_start)) if len(rows) > 1: date_end = StatusController.datetime_from_str(rows[len(rows) - 1]['taken_at'], '%Y-%m-%d %H:%M:%S%z') seconds_count = (date_end - date_start).total_seconds() days_count = seconds_count / (24 * 60 * 60) messages_count = len(rows) if (not date_from) and (not only_last_dialog): results.append('Длительность общения: {0:0.2f} суток'.format(days_count)) if not only_last_dialog: results.append('Средняя частота сообщений: {0:0.2f} в сутки'.format(messages_count / days_count)) max_dialog_question_interval = round((24 * 60 * 60) * 1.25) max_dialog_non_question_interval = round((24 * 60 * 60) * 0.75) max_dialog_hello_as_second_message_offset = round((24 * 60 * 60) * 0.25) dialog_hello_words = ['привет', 'приветствую', 'здравствуй', 'здравствуйте'] dialog_hello_phrases = ['доброе утро', 'доброго утра', 'добрый день', 'доброго дня', 'добрый вечер', 'доброго вечера'] dialog_hello_stop_context = ['-привет', 'всем привет', 'привет»', 'привет"'] msg_len_me = 0 msg_me_cnt = 0 msg_me_max_len = 0 msg_len_another = 0 msg_another_cnt = 0 msg_another_max_len = 0 me_deletes = 0 another_deletes = 0 me_hello = 0 another_hello = 0 me_words = [] another_words = [] dialogues = [] active_dialog = [] last_msg_from_id = None last_date = date_start last_msg_is_question = False edited_messages_me = {} edited_messages_another = {} edited_sequence_interrupted = {} last_message_row = None for row in rows: if not row['message']: row['message'] = '' if int(row['removed']) == 1 or int(row['is_removed']) == 1: if int(row['version']) == int(row['max_version']): if int(row['from_id']) == self.tg_client.me_user_id: me_deletes = me_deletes + 1 else: another_deletes = another_deletes + 1 else: if row['message_id'] not in edited_sequence_interrupted: for k_int in edited_sequence_interrupted.keys(): if type(edited_sequence_interrupted[k_int]) == dict: if edited_sequence_interrupted[k_int]['from_id'] != row['from_id']: edited_sequence_interrupted[k_int]['interrupts'].append(row['message_id']) if int(row['max_version']) > 1: if int(row['version']) < int(row['max_version']): if row['message_id'] not in edited_sequence_interrupted: edited_sequence_interrupted[row['message_id']] = { 'from_id': row['from_id'], 'interrupts': [] } else: if row['message_id'] in edited_sequence_interrupted: edited_sequence_interrupted[row['message_id']] = len(edited_sequence_interrupted[row['message_id']]['interrupts']) > 0 if last_message_row and (int(last_message_row['version']) < int(last_message_row['max_version'])) and (row['from_id'] != last_message_row['from_id']): edited_sequence_interrupted[row['message_id']] = True if int(row['version']) == int(row['max_version']): last_message_row = row if int(row['max_version']) > 1: if int(row['from_id']) == self.tg_client.me_user_id: if row['message_id'] not in edited_messages_me: edited_messages_me[row['message_id']] = [] edited_messages_me[row['message_id']].append(row) else: if row['message_id'] not in edited_messages_another: edited_messages_another[row['message_id']] = [] edited_messages_another[row['message_id']].append(row) if int(row['version']) == int(row['max_version']): message_lower = str(row['message']).lower() message_words = re.sub("[^\w]", " ", message_lower).split() message_words = list(filter(lambda x: x and self.is_valid_word(x, []), message_words)) message_hello_words = list(filter(lambda x: x in dialog_hello_words, message_words)) message_stop_contexts = list(filter(lambda x: message_lower.find(x) >= 0, dialog_hello_stop_context)) msg_from_id = int(row['from_id']) msg_is_question = str(row['message']).find('?') >= 0 msg_is_hello = (len(message_hello_words) > 0) and (len(message_stop_contexts) == 0) if not msg_is_hello: for d_ph in dialog_hello_phrases: if message_lower.find(d_ph) >= 0: msg_is_hello = True break if not skip_vocab: nform_list = [self.get_normal_form(x) for x in message_words] if msg_from_id == self.tg_client.me_user_id: me_words = me_words + nform_list else: another_words = another_words + nform_list if msg_is_hello: if msg_from_id == self.tg_client.me_user_id: me_hello = me_hello + 1 else: another_hello = another_hello + 1 msg_len = len(row['message']) if msg_from_id == self.tg_client.me_user_id: msg_len_me = msg_len_me + msg_len msg_me_cnt = msg_me_cnt + 1 if msg_len > msg_me_max_len: msg_me_max_len = msg_len else: msg_len_another = msg_len_another + msg_len msg_another_cnt = msg_another_cnt + 1 if msg_len > msg_another_max_len: msg_another_max_len = msg_len msg_date = StatusController.datetime_from_str(row['taken_at'], '%Y-%m-%d %H:%M:%S%z') if ( (len(active_dialog) == 0) or ( last_msg_is_question and ((msg_date - last_date).total_seconds() > max_dialog_question_interval) ) or ( not last_msg_is_question and ((msg_date - last_date).total_seconds() > max_dialog_non_question_interval) ) ): if len(active_dialog) > 0: dialogues.append(active_dialog) active_dialog = [] active_dialog.append(row) last_date = msg_date if last_msg_from_id != msg_from_id: last_msg_is_question = msg_is_question else: last_msg_is_question = last_msg_is_question or msg_is_question last_msg_from_id = msg_from_id for k_int in edited_sequence_interrupted.keys(): if type(edited_sequence_interrupted[k_int]) == dict: edited_sequence_interrupted[k_int] = len(edited_sequence_interrupted[k_int]['interrupts']) > 0 me_edit_stats = self.get_edit_stats(edited_messages_me, edited_sequence_interrupted) another_edit_stats = self.get_edit_stats(edited_messages_another, edited_sequence_interrupted) if len(active_dialog) > 0: dialogues.append(active_dialog) active_dialog = [] if only_last_dialog: dialogues = [dialogues[len(dialogues) - 1]] else: if len(dialogues) > 0: last_dialogue_date = StatusController.datetime_from_str(dialogues[len(dialogues) - 1][0]['taken_at'], '%Y-%m-%d %H:%M:%S%z') else: last_dialogue_date = None answers_me = 0 answers_wait_seconds_me = 0 answers_another = 0 answers_wait_seconds_another = 0 longest_len = 0 longest_dialog = None shortest_len = 0 dia_me_start = 0 dia_another_start = 0 dia_me_finish = 0 dia_another_finish = 0 dia_between_seconds = 0 dia_between_max = 0 dia_between_max_from = None dia_between_max_to = None dia_between_cnt = 0 last_dia_end = None for dial in dialogues: dial_len = len(dial) if (shortest_len == 0) or (dial_len < shortest_len): shortest_len = dial_len if (longest_len == 0) or (dial_len > longest_len): longest_len = dial_len longest_dialog = dial if dial_len > 0: first_dial = dial[0] last_dial = dial[len(dial) - 1] if int(first_dial['from_id']) == self.tg_client.me_user_id: dia_me_start = dia_me_start + 1 else: dia_another_start = dia_another_start + 1 if int(last_dial['from_id']) == self.tg_client.me_user_id: dia_me_finish = dia_me_finish + 1 else: dia_another_finish = dia_another_finish + 1 if last_dia_end: curr_first_dia_begin = StatusController.datetime_from_str(first_dial['taken_at'], '%Y-%m-%d %H:%M:%S%z') dia_between_seconds_curr = (curr_first_dia_begin - last_dia_end).total_seconds() dia_between_seconds = dia_between_seconds + dia_between_seconds_curr dia_between_cnt = dia_between_cnt + 1 if dia_between_seconds_curr > dia_between_max: dia_between_max = dia_between_seconds_curr dia_between_max_from = last_dia_end dia_between_max_to = curr_first_dia_begin last_dia_end = StatusController.datetime_from_str(last_dial['taken_at'], '%Y-%m-%d %H:%M:%S%z') last_msg_id = None last_msg_date = None for dia in dial: msg_date = StatusController.datetime_from_str(dia['taken_at'], '%Y-%m-%d %H:%M:%S%z') if last_msg_id and (last_msg_id != int(dia['from_id'])): seconds_between = (msg_date - last_msg_date).total_seconds() if seconds_between > (60 * 60 * 4) and ((last_msg_date.time().hour < 6) or (last_msg_date.time().hour >= 22)): # somebody just sleep last_msg_date = msg_date last_msg_id = int(dia['from_id']) continue if last_msg_id == self.tg_client.me_user_id: answers_another = answers_another + 1 answers_wait_seconds_another = answers_wait_seconds_another + seconds_between else: answers_me = answers_me + 1 answers_wait_seconds_me = answers_wait_seconds_me + seconds_between last_msg_date = msg_date last_msg_id = int(dia['from_id']) if dia_between_cnt > 0: dia_between_time = dia_between_seconds / dia_between_cnt dia_between_time = "{0:0.2f} сут.".format(dia_between_time / (60 * 60 * 24)) dia_between_time_max = "{0:0.2f} сут.".format(dia_between_max / (60 * 60 * 24)) dia_between_time_max = StatusController.datetime_to_str(dia_between_max_from) + ' --- ' + StatusController.datetime_to_str(dia_between_max_to) + ' ('+dia_between_time_max+')' else: dia_between_time = '?' dia_between_time_max = '?' if answers_another > 0: answers_wait_seconds_another = answers_wait_seconds_another / answers_another another_answer_time = "{0:0.2f} мин.".format(answers_wait_seconds_another / 60) else: another_answer_time = '?' if answers_me > 0: answers_wait_seconds_me = answers_wait_seconds_me / answers_me me_answer_time = "{0:0.2f} мин.".format(answers_wait_seconds_me / 60) else: me_answer_time = '?' if not date_from: self.tg_client.entity_controller.set_entity_answer_sec(user_id, answers_wait_seconds_me, answers_wait_seconds_another) longest_dates = '' longest_hours = 0 if longest_len > 1: msg_date1 = StatusController.datetime_from_str(longest_dialog[0]['taken_at'], '%Y-%m-%d %H:%M:%S%z') msg_date2 = StatusController.datetime_from_str(longest_dialog[longest_len - 1]['taken_at'], '%Y-%m-%d %H:%M:%S%z') longest_hours = (msg_date2 - msg_date1).total_seconds() / (24 * 60 * 60) longest_dates = StatusController.datetime_to_str(msg_date1) + ' --- ' + StatusController.datetime_to_str(msg_date2) valid_word_types = ['СУЩ', 'МЕЖД'] valid_word_types_str = (",".join(valid_word_types)).lower() me_top_10 = None me_last_cnt = None me_words_count = 0 all_words_me = {} if (not skip_vocab) and (len(me_words) > 0): for word in me_words: if word and (word not in all_words_me): all_words_me[word] = True me_words_count = len(all_words_me) me_words = list(filter(lambda x: x and self.is_valid_word(x, valid_word_types), me_words)) wordlist = sorted(me_words) wordfreq = [wordlist.count(p) for p in wordlist] dic = dict(zip(wordlist, wordfreq)) me_words = list(sorted(dic.items(), key=lambda x: x[1], reverse=True)) words = me_words half_words = round(len(words) / 2) if half_words < 3: half_words = 3 elif half_words > 15: half_words = 15 top_10 = list(filter(lambda x: x[1] > 1, words[0:half_words])) top_10 = list(map(lambda x: '**' + str(x[0]) + '** (' + str(x[1]) + ')', top_10)) last_word, last_cnt = words[len(words) - 1] last_cnt_words = map(lambda x: x[0], filter(lambda s: s[1] == last_cnt, words)) last_cnt_words = list(sorted(last_cnt_words, key=lambda x: len(x), reverse=True)) last_cnt_cnt = len(last_cnt_words) - half_words if last_cnt_cnt < 3: last_cnt_cnt = 3 elif last_cnt_cnt > 10: last_cnt_cnt = 10 last_cnt_words = last_cnt_words[0:last_cnt_cnt] me_top_10 = top_10 me_last_cnt = last_cnt_words another_top_10 = None another_last_cnt = None another_words_count = 0 all_words_another = {} if (not skip_vocab) and (len(another_words) > 0): for word in another_words: if word and (word not in all_words_another): all_words_another[word] = True another_words_count = len(all_words_another) another_words = list(filter(lambda x: x and self.is_valid_word(x, valid_word_types), another_words)) wordlist = sorted(another_words) wordfreq = [wordlist.count(p) for p in wordlist] dic = dict(zip(wordlist, wordfreq)) another_words = list(sorted(dic.items(), key=lambda x: x[1], reverse=True)) words = another_words half_words = round(len(words) / 2) if half_words < 3: half_words = 3 elif half_words > 15: half_words = 15 top_10 = list(filter(lambda x: x[1] > 1, words[0:half_words])) top_10 = list(map(lambda x: '**' + str(x[0]) + '** (' + str(x[1]) + ')', top_10)) last_word, last_cnt = words[len(words) - 1] last_cnt_words = map(lambda x: x[0], filter(lambda s: s[1] == last_cnt, words)) last_cnt_words = list(sorted(last_cnt_words, key=lambda x: len(x), reverse=True)) last_cnt_cnt = len(last_cnt_words) - half_words if last_cnt_cnt < 3: last_cnt_cnt = 3 elif last_cnt_cnt > 10: last_cnt_cnt = 10 last_cnt_words = last_cnt_words[0:last_cnt_cnt] another_top_10 = top_10 another_last_cnt = last_cnt_words me_not_another_words_count = 0 me_not_another_top = None another_not_me_words_count = 0 another_not_me_top = None if (not skip_vocab) and (len(me_words) > 0) and (len(another_words) > 0): me_not_another_top = [] for word in me_words: if word[0] not in all_words_another: me_not_another_top.append(word) me_not_another_words_count = len(me_not_another_top) me_not_another_top = me_not_another_top[:15] me_not_another_top = list(map(lambda x: '**' + str(x[0]) + '** (' + str(x[1]) + ')', me_not_another_top)) another_not_me_top = [] for word in another_words: if word[0] not in all_words_me: another_not_me_top.append(word) another_not_me_words_count = len(another_not_me_top) another_not_me_top = another_not_me_top[:15] another_not_me_top = list(map(lambda x: '**' + str(x[0]) + '** (' + str(x[1]) + ')', another_not_me_top)) results.append('Сообщений '+another_name+': {0} ({1:0.3f} Kb.)'.format(msg_another_cnt, msg_len_another/1024)) results.append('Сообщений '+me_name+': {0} ({1:0.3f} Kb.)'.format(msg_me_cnt, msg_len_me/1024)) if msg_another_cnt > 0: results.append('Средняя длина сообщения '+another_name+': {0:0.2f} сим.'.format(msg_len_another / msg_another_cnt)) if msg_me_cnt > 0: results.append('Средняя длина сообщения '+me_name+': {0:0.2f} сим.'.format(msg_len_me / msg_me_cnt)) results.append('Самое длинное сообщение '+another_name+': ' + str(msg_another_max_len) + ' сим.') results.append('Самое длинное сообщение '+me_name+': ' + str(msg_me_max_len) + ' сим.') results.append('Число приветствий от '+another_name+': ' + str(another_hello)) results.append('Число приветствий от '+me_name+': ' + str(me_hello)) if not only_last_dialog: results.append('') results.append('Число диалогов: ' + str(len(dialogues))) results.append('Сообщений в самом коротком диалоге: ' + str(shortest_len)) results.append('Сообщений в самом длинном диалоге: ' + str(longest_len)) results.append('Самый длинный диалог: ' + longest_dates + ' ({0:0.3f} сут)'.format(longest_hours)) if len(dialogues) > 0: if dia_between_time != '?': results.append('Среднее время между диалогами: ' + str(dia_between_time)) if dia_between_time_max != '?': results.append('Самое большое время между диалогами: ' + str(dia_between_time_max)) results.append('Инициатор диалога ' + another_name + ': {0:0.2f} %'.format(100 * dia_another_start / len(dialogues))) results.append('Инициатор диалога ' + me_name + ': {0:0.2f} %'.format(100 * dia_me_start / len(dialogues))) results.append('Завершитель диалога ' + another_name + ': {0:0.2f} %'.format(100 * dia_another_finish / len(dialogues))) results.append('Завершитель диалога ' + me_name + ': {0:0.2f} %'.format(100 * dia_me_finish / len(dialogues))) else: results.append('Сообщений в диалоге: ' + str(longest_len)) results.append('Продолжительность диалога: ' + longest_dates + ' ({0:0.3f} сут)'.format(longest_hours)) if dia_me_start > 0: results.append('Инициатор: ' + me_name) elif dia_another_start > 0: results.append('Инициатор: ' + another_name) if dia_me_finish > 0: results.append('Завершитель: ' + me_name) elif dia_another_finish > 0: results.append('Завершитель: ' + another_name) if another_answer_time != '?': results.append('В среднем ' + another_name + ' отвечает за: ' + another_answer_time) if me_answer_time != '?': results.append('В среднем ' + me_name + ' отвечает за: ' + me_answer_time) results.append('') if me_edit_stats['edited_messages_count'] > 0 or another_edit_stats['edited_messages_count'] > 0: if (not date_from) and (not only_last_dialog): results.append('За время активности скрипта ('+str(days_a)+' сут.):') results.append('Отредактировано сообщений {}: {}'.format(another_name, another_edit_stats['edited_messages_count'])) results.append('Отредактировано сообщений {}: {}'.format(me_name, me_edit_stats['edited_messages_count'])) results.append('Отредактировано сообщений {} после ответа на него: {}'.format(another_name, another_edit_stats['sequence_interrupted_cnt'])) results.append('Отредактировано сообщений {} после ответа на него: {}'.format(me_name, me_edit_stats['sequence_interrupted_cnt'])) results.append('Процент редактируемых сообщений {0}: {1:0.2f}%'.format(another_name, 100 * another_edit_stats['edited_messages_count'] / msg_another_cnt)) results.append('Процент редактируемых сообщений {0}: {1:0.2f}%'.format(me_name, 100 * me_edit_stats['edited_messages_count'] / msg_me_cnt)) if another_edit_stats['max_1_message_edits'] > 0: results.append('Макс. число правок одного сообщения {}: {} ("{}")'.format(another_name, another_edit_stats['max_1_message_edits'], self.cut_text(another_edit_stats['max_edits_message']))) if me_edit_stats['max_1_message_edits'] > 0: results.append('Макс. число правок одного сообщения {}: {} ("{}")'.format(me_name, me_edit_stats['max_1_message_edits'], self.cut_text(me_edit_stats['max_edits_message']))) if another_edit_stats['max_1_message_diff_percent'] > 0: results.append('Макс. процент правок одного сообщения {0}: {1:0.2f}% ("{2}")'.format(another_name, another_edit_stats['max_1_message_diff_percent'], self.cut_text(another_edit_stats['max_changed_message']))) if me_edit_stats['max_1_message_diff_percent'] > 0: results.append('Макс. процент правок одного сообщения {0}: {1:0.2f}% ("{2}")'.format(me_name, me_edit_stats['max_1_message_diff_percent'], self.cut_text(me_edit_stats['max_changed_message']))) results.append('') results.append('В среднем правок на 1 сообщение {0}: {1:0.2f}'.format(another_name, another_edit_stats['mid_1_message_edits'])) results.append('В среднем правок на 1 сообщение {0}: {1:0.2f}'.format(me_name, me_edit_stats['mid_1_message_edits'])) results.append('Средний суммарный процент изменений редактируемых сообщений {0}: {1:0.3f}%'.format(another_name, another_edit_stats['message_edit_mid_summ_percent'])) results.append('Средний суммарный процент изменений редактируемых сообщений {0}: {1:0.3f}%'.format(me_name, me_edit_stats['message_edit_mid_summ_percent'])) results.append('Среднее время между правками одного сообщения {0}: {1:0.2f} мин.'.format(another_name, another_edit_stats['message_edit_mid_time_sec'] / 60)) results.append('Среднее время между правками одного сообщения {0}: {1:0.2f} мин.'.format(me_name, me_edit_stats['message_edit_mid_time_sec'] / 60)) results.append('') results.append('Средняя правка (число замен / вставок / удалений) {0}: {1:0.2f} / {2:0.2f} / {3:0.2f}'.format(another_name, another_edit_stats['replaces_count_avg'], another_edit_stats['inserts_count_avg'], another_edit_stats['deletes_count_avg'])) results.append('Средняя правка (число замен / вставок / удалений) {0}: {1:0.2f} / {2:0.2f} / {3:0.2f}'.format(me_name, me_edit_stats['replaces_count_avg'], me_edit_stats['inserts_count_avg'], me_edit_stats['deletes_count_avg'])) results.append('') results.append('Удалений сообщений ' + another_name + ': ' + str(another_deletes)) results.append('Удалений сообщений ' + me_name + ': ' + str(me_deletes)) if me_top_10 or another_top_10: results.append('') results.append('Различных слов ' + another_name + ' в диалогах: ' + str(another_words_count)) results.append('Различных слов ' + me_name + ' в диалогах: ' + str(me_words_count)) results.append('') results.append('Самые частые слова ('+valid_word_types_str+') ' + another_name + ' в диалогах: ' + (", ".join(another_top_10)) + '') results.append('') results.append('Самые частые слова ('+valid_word_types_str+') ' + me_name + ' в диалогах: ' + (", ".join(me_top_10)) + '') results.append('') results.append('Самые редкие слова ('+valid_word_types_str+') ' + another_name + ' в диалогах: ' + (", ".join(another_last_cnt)) + '') results.append('') results.append('Самые редкие слова ('+valid_word_types_str+') ' + me_name + ' в диалогах: ' + (", ".join(me_last_cnt)) + '') if me_not_another_words_count > 0: results.append('') results.append('Слова ' + me_name + ' ('+valid_word_types_str+'), которые ' + another_name + ' ни разу не использовал: **' + str(me_not_another_words_count) +'** шт. Самые частые: ' + (", ".join(me_not_another_top)) + '') if another_not_me_words_count > 0: results.append('') results.append('Слова ' + another_name + ' ('+valid_word_types_str+'), которые ' + me_name + ' ни разу не использовал: **' + str(another_not_me_words_count) +'** шт. Самые частые: ' + (", ".join(another_not_me_top)) + '') CacheHelper().save_to_cache('normal_forms', 'dialog_stats', self.normal_form_cache) CacheHelper().save_to_cache('word_type_forms', 'dialog_stats', self.word_type_form_cache) return { 'results': results, 'last_dialogue_date': last_dialogue_date }
async def message_handler(self, event): if type(event.original_update) != UpdateNewMessage: return try: await self.init_bot_entity() data = event.original_update if data.message.from_id == self.bot_entity_id: return MainHelper().play_notify_sound('notify_when_my_bot_message') if data.message.id and data.message.from_id and ( data.message.from_id != self.tg_client.me_user_id): msg_entity_name = await self.tg_client.get_entity_name( data.message.from_id, 'User') if msg_entity_name: print( StatusController.datetime_to_str(datetime.now()) + ' Message to my bot from "' + msg_entity_name + '"') print('<<< ' + str(data.message.message)) t_date = StatusController.tg_datetime_to_local_datetime( data.message.date) self.tg_client.add_message_to_db(self.bot_entity_id, 'Bot', data.message.from_id, self.bot_entity_id, data.message.id, data.message.message, t_date, 0) elif data.message.id and data.message.from_id and ( data.message.from_id == self.tg_client.me_user_id): t_date = StatusController.tg_datetime_to_local_datetime( data.message.date) self.tg_client.add_message_to_db(self.bot_entity_id, 'Bot', data.message.from_id, self.bot_entity_id, data.message.id, data.message.message, t_date, 0) elif not data.message.id and data.message.from_id: t_date = StatusController.now_local_datetime() self.tg_client.add_message_to_db(self.bot_entity_id, 'Bot', data.message.from_id, self.bot_entity_id, None, data.message.message, t_date, 0) msg_entity_name = await self.tg_client.get_entity_name( data.message.from_id, 'User') if msg_entity_name: print( StatusController.datetime_to_str(datetime.now()) + ' Command to my bot from "' + msg_entity_name + '"') print('<<< ' + str(data.message.message)) forward_data = None if data.message.id: bot_chat = await event.get_input_chat() if data.message.fwd_from: forward_data = { 'from_id': data.message.fwd_from.from_id, 'date_from': data.message.fwd_from.date } else: try: bot_chat = await self.get_input_entity( PeerUser(data.message.from_id)) except: traceback.print_exc() bot_chat = None if not bot_chat: bot_chat = self.tg_client.entity_controller.get_user_bot_chat( data.message.from_id) if not bot_chat: print("Can't get chat!") return try: ee_name = await self.tg_client.get_entity_name( bot_chat.user_id, 'User') except: ee_name = str(bot_chat.user_id) self.tg_client.entity_controller.add_entity_db_name( bot_chat.user_id, 'User', ee_name) self.tg_client.entity_controller.save_user_bot_chat(bot_chat) if data.message.message == '/start': self.tg_client.entity_controller.save_user_bot_last_version( bot_chat.user_id, MainHelper().get_config_float_value( 'main', 'actual_version')) if data.message.id: self.tg_client.bot_controller.set_message_for_user( data.message.from_id, data.message.id, False) await self.tg_client.bot_controller.bot_command( data.message.message, data.message.from_id, self.bot_entity_id, 'Bot', forward_data) except: traceback.print_exc()
async def cmd_user_info(self, to_id, params): from_id = to_id for_id = await self.tg_bot_controller.get_from_id_param(to_id, params) entity = await self.tg_bot_controller.tg_client.get_entity(for_id) res = [] res.append('ID: ' + str(entity.id)) if entity.username: res.append('Логин: ' + str(entity.username)) if entity.phone: res.append('Телефон: ' + str(entity.phone)) if entity.first_name: res.append('Имя: ' + str(entity.first_name)) if entity.last_name: res.append('Фамилия: ' + str(entity.last_name)) res.append('') if to_id != for_id: if entity.mutual_contact: res.append('У тебя в контактах, ты у него в контактах') elif entity.contact: res.append('У тебя в контактах') last_date = None if type(entity.status) == UserStatusOnline: status_name = 'Онлайн' elif type(entity.status) == UserStatusOffline: status_name = 'Оффлайн' last_date = StatusController.tg_datetime_to_local_datetime( entity.status.was_online) last_date = StatusController.datetime_to_str(last_date) elif entity.status: status_name = 'Не отслеживается (' + entity.status.to_dict( )['_'] + ')' elif entity.bot: status_name = 'Бот' else: status_name = 'Неизвестно' res.append('Статус: ' + status_name) if last_date: res.append('Был в сети: ' + last_date) res.append('') sessions_cnt = self.tg_bot_controller.tg_client.status_controller.get_user_activity_sessions_count( entity.id) if sessions_cnt > 0: res.append('Активность отслеживается (сохранено сессий: ' + str(sessions_cnt) + ')') else: res.append('Активность не отслеживается') m_types = self.tg_bot_controller.tg_client.status_controller.get_user_messages_entity_types( entity.id) if m_types and len(m_types) > 0: res.append('Сообщения отслеживаются (' + (", ".join(m_types)) + ')') else: res.append('Сообщения не отслеживается') stat_msg = await self.tg_bot_controller.tg_client.status_controller.get_user_aa_statistics_text( entity.id, False) if stat_msg: res.append('') res.append(stat_msg) stat_msg = await self.tg_bot_controller.tg_client.status_controller.get_stat_user_messages( entity.id, from_id) if stat_msg: res.append('') res.append(stat_msg) await self.send_message_to_user(to_id, "\n".join(res))
async def cmd_activity_today(self, from_id, params): to_id = from_id from_id = await self.tg_bot_controller.get_from_id_param( from_id, params) now_str = StatusController.datetime_to_str(datetime.now(), '%Y-%m-%d') await self.send_activity_message(from_id, to_id, now_str, True, "diap")