示例#1
0
    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] за неделю")
示例#3
0
 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])
示例#4
0
 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()
示例#6
0
 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] за сегодня")
示例#8
0
 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
示例#9
0
    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)
示例#10
0
    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()
示例#11
0
    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
        }
示例#12
0
    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()
示例#13
0
    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))
示例#14
0
 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")