Ejemplo n.º 1
0
 async def force_add_user(self, user_id, message=None):
     if not self.aa_options['is_set']:
         self.tg_bot_controller.tg_client.me_last_activity = datetime.now(
         ) + timedelta(minutes=-10)
         if not message:
             message = str(MainHelper().get_config_value(
                 'chat_bot', 'bot_aa_default_message'))
         self.reset_aa()
         self.reset_user_setup()
         self.aa_options = {
             'is_set': True,
             'from_mode': 4,
             'from_user_ids': [],
             'activate_after_minutes': 10.0,
             'answer_after_minutes': 2.0,
             'show_bot': True,
             'allow_bot_chat': True,
             'notify_entity_id': None,
             'message': ''
         }
     self.aa_options['from_mode'] = 4
     if user_id not in self.aa_options['from_user_ids']:
         self.aa_options['from_user_ids'].append(user_id)
     if user_id in self.aa_not_for_users:
         self.aa_not_for_users.remove(user_id)
     if user_id in self.aa_for_users:
         del self.aa_for_users[user_id]
     if message:
         self.aa_options['message'] = message
     await self.on_user_message_to_me(user_id, '---')
Ejemplo n.º 2
0
 def do_start(self):
     print('Starting of bot')
     self.start(bot_token=MainHelper().get_config_value('tg_bot', 'token'))
     self.loop.run_until_complete(self.init_bot_entity())
     self.add_event_handler(self.message_handler, event=events.NewMessage)
     self.add_event_handler(self.callback_handler,
                            event=events.CallbackQuery)
Ejemplo n.º 3
0
 async def bot_check_user_message(self, message_text, from_id, dialog_entity_id, dialog_entity_type):
     bot_check_message = message_text.replace(',', ' ')
     bot_check_message = self.adapt_command(bot_check_message)
     if self.is_active_for_user(dialog_entity_id, False) and bot_check_message.startswith(MainHelper().get_config_value('chat_bot', 'bot_ignore_prefix')):
         return False
     if self.is_active_for_user(dialog_entity_id, False) and bot_check_message.startswith(MainHelper().get_config_value('chat_bot', 'bot_end_prefix')):
         bot_message = bot_check_message.replace(MainHelper().get_config_value('chat_bot', 'bot_end_prefix'), '', 1).strip()
         if not bot_message:
             bot_message = MainHelper().get_config_value('chat_bot', 'bot_empty_goodbuy')
         print('Bot command:')
         self.tg_client.sprint('<<< ' + bot_message.replace('\n', ' \\n '))
         await self.bot_command(bot_message, from_id, dialog_entity_id, dialog_entity_type)
         self.stop_chat_with_user(dialog_entity_id)
         return True
     elif self.is_active_for_user(dialog_entity_id, False) or ((self.tg_client.selected_user_activity == dialog_entity_id) and (bot_check_message.startswith(MainHelper().get_config_value('chat_bot', 'bot_start_prefix')))):
         if not self.is_active_for_user(dialog_entity_id, False):
             bot_message = bot_check_message.replace(MainHelper().get_config_value('chat_bot', 'bot_start_prefix'), '', 1).strip()
         else:
             bot_message = message_text.strip()
         if not bot_message:
             bot_message = MainHelper().get_config_value('chat_bot', 'bot_empty_greet')
         print('Bot command:')
         self.tg_client.sprint('<<< ' + message_text.replace('\n', ' \\n '))
         await self.bot_command(bot_message, from_id, dialog_entity_id, dialog_entity_type)
         return True
     return False
Ejemplo n.º 4
0
    def chatbot_message_response(self, message_text, user_id):
        try:
            weather_words = str(MainHelper().get_config_value('chat_bot', 'bot_weather_keywords'))
            weather_words = weather_words.split('|')
            message_text_words = re.findall(r'\w+', message_text)
            intersect_words = set(message_text_words).intersection(weather_words)
            is_weather = (len(intersect_words) > 0) and MainHelper().get_config_value('chat_bot', 'bot_weather_owm_api_key')
            if not is_weather:
                api = apiai.ApiAI(str(MainHelper().get_config_value('chat_bot', 'bot_client_token')), str(MainHelper().get_config_value('chat_bot', 'bot_session_name')) + '_' + str(user_id))
            else:
                api = apiai.ApiAI(str(MainHelper().get_config_value('chat_bot', 'bot_client_token_weather')), str(MainHelper().get_config_value('chat_bot', 'bot_session_name_weather')) + '_' + str(user_id))
            request = api.text_request()
            request.lang = 'ru'
            request.query = message_text
            response_json = json.loads(request.getresponse().read().decode('utf-8'))

            if is_weather:
                city = None
                if response_json['result']['parameters'] and response_json['result']['parameters']['address'] and response_json['result']['parameters']['address']['city']:
                    city = response_json['result']['parameters']['address']['city']
                if not city:
                    city = str(MainHelper().get_config_value('chat_bot', 'bot_weather_city_default'))
                owm = pyowm.OWM(str(MainHelper().get_config_value('chat_bot', 'bot_weather_owm_api_key')), language="ru", use_ssl=True)
                observation = owm.weather_at_place(city)
                w = observation.get_weather()
                status = w.get_detailed_status() + ' (облачность '+str(w.get_clouds())+'%)'
                pressure_res = w.get_pressure()
                pressure = str(pressure_res.get('press')) + ' мм.рт.ст.'
                visibility_distance = str(w.get_visibility_distance()) + ' м.'
                wind_res = w.get_wind()
                wind_speed = str(wind_res.get('speed')) + ' м/с'
                humidity = str(w.get_humidity()) + '%'
                celsius_result = w.get_temperature('celsius')
                temp_min_celsius = str(celsius_result.get('temp_min')) + '°C'
                temp_max_celsius = str(celsius_result.get('temp_max')) + '°C'
                response = "Текущая погода в г. " + city + ": \n" + \
                           status + "\n" + \
                           "Температура:\n    Макс: " + temp_max_celsius + "\n    Мин: " + temp_min_celsius + "\n"+\
                           "Влажность: " + humidity + "\n"+\
                           "Давление: " + pressure + "\n"+\
                           "Видимость: " + visibility_distance + "\n"+\
                           "Ветер: " + wind_speed + "\n"
            else:
                response = response_json['result']['fulfillment']['speech']
            if response:
                return response
        except:
            traceback.print_exc()
            return str(MainHelper().get_config_value('chat_bot', 'bot_error_message'))
        return str(MainHelper().get_config_value('chat_bot', 'bot_cant_understand_message'))
Ejemplo n.º 5
0
 async def send_activity_message(self,
                                 for_id,
                                 send_to_id,
                                 date_activity=None,
                                 result_only_time=False,
                                 a_type="plot_img",
                                 img_caption="График активности [user]"):
     for_name = await self.tg_bot_controller.tg_client.get_entity_name(
         for_id)
     status_results = await self.tg_bot_controller.tg_client.status_controller.print_user_activity(
         for_id, for_name, a_type, date_activity, result_only_time)
     status_results = status_results.strip().splitlines()
     last_str = ''
     if a_type == "plot_img":
         last_str = str(status_results.pop())
     if last_str and last_str.startswith(MainHelper(
     ).get_config_root_folder_value('main', 'files_folder') + "/"):
         u_link = await self.user_link(for_id, for_name)
         await self.send_file_to_user(send_to_id, last_str,
                                      img_caption.replace('[user]', u_link),
                                      True)
     else:
         full_results = "\n".join(status_results)
         if (len(full_results) + 8) >= 4096:
             status_results.reverse()
             buff_len = 1
             while buff_len > 0:
                 buff = []
                 buff_len = 0
                 while (len(status_results) > 0) and (buff_len + len(
                         status_results[len(status_results) - 1]) +
                                                      8) < 4096:
                     last_s = status_results.pop()
                     buff.append(last_s)
                     buff_len = buff_len + len(last_s) + 1
                 if buff_len > 0:
                     await self.send_message_to_user(
                         send_to_id, '```\n' + ("\n".join(buff)) + '\n```')
                     if len(status_results) > 0:
                         await asyncio.sleep(0.75)
         else:
             await self.send_message_to_user(
                 send_to_id, '```\n' + full_results + '\n```')
    async def on_timer(self):
        if not self.branch_parent.has_insta_lib:
            return
        if self.last_stories_check_time and (
                datetime.now() - self.last_stories_check_time
        ).total_seconds() < MainHelper().get_config_int_value(
                'instagram', 'check_story_delay_seconds'):
            return
        self.last_stories_check_time = datetime.now()

        ustories = self.tg_bot_controller.tg_client.entity_controller.get_entity_db_option_list(
            'stories_accounts')
        if ustories and (len(ustories) > 0):
            ustories = str("\n".join(ustories)).splitlines()
            ustories = list(dict.fromkeys(ustories))
        else:
            return
        self.branch_parent.do_login_if_need()
        if not self.branch_parent.api:
            print('API-клиент не был инициализирован!')
            return

        insta_id_cache = self.tg_bot_controller.tg_client.entity_controller.get_entity_db_option(
            0, 'insta_user_ids', True, {})

        for username in ustories:
            if username in insta_id_cache:
                user_id = insta_id_cache[username]
            else:
                info = await self.branch_parent.get_user_info_by_username(
                    None, username, False)
                if not info:
                    continue
                user_id = int(info['user']['pk'])
                insta_id_cache[username] = user_id
            self.save_user_stories(user_id, username)
        self.download_stories()

        self.tg_bot_controller.tg_client.entity_controller.set_entity_db_option(
            0, 'insta_user_ids', insta_id_cache, True)
Ejemplo n.º 7
0
 async def send_version_message_to_all_bot_users(self):
     sent_count = 0
     try:
         version_messages = self.get_version_messages()
         new_ver = MainHelper().get_config_float_value(
             'main', 'actual_version')
         new_ver_title = MainHelper().get_config_value(
             'main', 'new_version_title')
         new_ver_help = MainHelper().get_config_value(
             'main', 'new_version_help')
         result_title = new_ver_title.replace(
             '[actual_version]', "{0:0.2f}".format(new_ver)).replace(
                 '[bot_name]',
                 MainHelper().get_config_value('tg_bot', 'bot_username'))
         result_title = result_title + '\n' + new_ver_help
         chats = self.tg_client.entity_controller.get_all_bot_users_chats()
         if chats and len(chats) > 0:
             for chat in chats:
                 user_last_version = self.tg_client.entity_controller.get_user_bot_last_version(
                     chat.user_id)
                 if not user_last_version:
                     user_last_version = 0.0
                 user_last_version = float(user_last_version)
                 result_user_message = []
                 for version_message in version_messages:
                     if version_message['version'] > user_last_version:
                         version_message_text = 'Список изменений версии {0:0.2f}:\n'.format(
                             version_message['version'])
                         version_message_text = version_message_text + version_message[
                             'message']
                         result_user_message.append(version_message_text)
                 if len(result_user_message) > 0:
                     result_user_message = result_title + '\n--------\n' + (
                         "\n--------\n".join(result_user_message)).strip()
                     self.tg_client.entity_controller.save_user_bot_last_version(
                         chat.user_id, new_ver)
                     await self.send_message(chat, result_user_message)
                     sent_count = sent_count + 1
     except:
         traceback.print_exc()
     return sent_count
Ejemplo n.º 8
0
 async def on_bot_message(self, message, from_id):
     if (self.setup_step == 0) or (self.setup_user_id != from_id):
         return await super().on_bot_message(message, from_id)
     if not self.is_in_current_branch(from_id):
         return False
     message = str(message).strip()
     if self.setup_step == 1:
         num_msg = int(message)
         if (num_msg >= 0) and (num_msg <= 4):
             self.aa_options['from_mode'] = num_msg
             self.aa_options['from_user_ids'] = []
             if num_msg == 4:
                 await self.next_setup_step(2)
             else:
                 await self.next_setup_step(3)
         else:
             await self.next_setup_step(1)
     elif self.setup_step == 2:
         self.aa_options['from_user_ids'] = []
         logins = message.lower().split(',')
         for login_s in logins:
             login = str(login_s).strip()
             entity = None
             try:
                 entity = await self.tg_bot_controller.tg_client.get_entity(
                     login)
             except ValueError:
                 try:
                     entity = await self.tg_bot_controller.tg_client.get_entity(
                         PeerUser(int(login)))
                 except:
                     pass
             if entity and (type(entity) == User):
                 if entity.id not in self.aa_options['from_user_ids']:
                     self.aa_options['from_user_ids'].append(entity.id)
             else:
                 await self.send_message_to_user(from_id,
                                                 'Сущность не опознана - ' +
                                                 str(login),
                                                 do_set_next=False)
         if len(self.aa_options['from_user_ids']) > 0:
             await self.next_setup_step(3)
         else:
             await self.next_setup_step(2)
     elif self.setup_step == 3:
         num_msg = float(message)
         if num_msg < 0.01:
             num_msg = 0.0
         elif num_msg > 999999999999:
             num_msg = 999999999999
         self.aa_options['activate_after_minutes'] = num_msg
         await self.next_setup_step()
     elif self.setup_step == 4:
         num_msg = float(message)
         if num_msg < 0.01:
             num_msg = 0.0
         elif num_msg > 999999999999:
             num_msg = 999999999999
         self.aa_options['answer_after_minutes'] = num_msg
         await self.next_setup_step()
     elif self.setup_step == 5:
         message = message.lower()
         self.aa_options['show_bot'] = message in self.yes_variants
         await self.next_setup_step()
     elif self.setup_step == 6:
         message = message.lower()
         self.aa_options['allow_bot_chat'] = message in self.yes_variants
         await self.next_setup_step()
     elif self.setup_step == 7:
         if not message or (message in self.no_variants):
             message = str(MainHelper().get_config_value(
                 'chat_bot', 'bot_aa_default_message'))
         elif re.match(r"[0-9]{1,2}:[0-9]{1,2}", message):
             d_msg = message
             message = str(MainHelper().get_config_value(
                 'chat_bot', 'bot_aa_default_message_time'))
             message = message.replace('[datetime]', d_msg)
         self.aa_options['message'] = message
         await self.next_setup_step()
     elif self.setup_step == 200:
         self.aa_options['message'] = str(MainHelper().get_config_value(
             'chat_bot', 'bot_aa_default_message_time'))
         self.aa_options['message'] = self.aa_options['message'].replace(
             '[datetime]', message)
         self.reset_user_setup()
         await self.send_message_to_user(from_id, 'Сообщение изменено!')
     return True
Ejemplo n.º 9
0
 async def next_setup_step(self, next_step=None, from_user_id=None):
     if not from_user_id:
         from_user_id = self.setup_user_id
     if next_step is not None:
         self.setup_step = next_step
     else:
         self.setup_step = self.setup_step + 1
     if self.setup_step == 1:
         msg = '**Шаг 1**\n\n'
         msg = msg + 'Для сообщений от кого должен срабатывать автоответчик? (уровень доступа)\n\n'
         msg = msg + '  0 - ото всех\n'
         msg = msg + '  1 - от моих контактов\n'
         msg = msg + '  2 - от моих взаимных контактов\n'
         msg = msg + '  3 - от выбранных в общем списке пользователей\n'
         msg = msg + '  4 - указать логины/ID\n'
         await self.send_message_to_user(from_user_id,
                                         msg.strip(),
                                         buttons=self.cmd_to_btns(
                                             {
                                                 '0': '0',
                                                 '1': '1',
                                                 '2': '2',
                                                 '3': '3',
                                                 '4': 'указать логины',
                                             }, 4),
                                         do_set_next=False)
     elif self.setup_step == 2:
         msg = '**Шаг 1.1**\n\n'
         msg = msg + 'Перечислите логины/ID через запятую'
         await self.send_message_to_user(from_user_id,
                                         msg.strip(),
                                         do_set_next=False)
     elif self.setup_step == 3:
         msg = '**Шаг 2**\n\n'
         msg = msg + 'Сколько минут ' + self.tg_bot_controller.tg_client.me_user_name + ' должен быть не в сети для срабатывания автоответчика?'
         await self.send_message_to_user(from_user_id,
                                         msg.strip(),
                                         buttons=self.cmd_to_btns(
                                             {
                                                 '1': '1 мин',
                                                 '5': '5 мин',
                                                 '10': '10 мин',
                                                 '30': '30 мин',
                                                 '60': '1 ч',
                                                 '120': '2 ч',
                                                 '360': '3 ч',
                                                 '480': '4 ч',
                                                 '720': '6 ч',
                                             }, 3),
                                         do_set_next=False)
     elif self.setup_step == 4:
         msg = '**Шаг 3**\n\n'
         msg = msg + 'Через сколько минут после сообщения автоответчик сработает?'
         await self.send_message_to_user(from_user_id,
                                         msg.strip(),
                                         buttons=self.cmd_to_btns(
                                             {
                                                 '0': 'сразу же',
                                                 '0.5': '0.5 мин',
                                                 '1': '1 мин',
                                                 '2': '2 мин',
                                                 '5': '5 мин',
                                                 '10': '10 мин',
                                                 '20': '20 мин',
                                                 '30': '30 мин',
                                                 '60': '1 ч',
                                             }, 3),
                                         do_set_next=False)
     elif self.setup_step == 5:
         msg = '**Шаг 4**\n\n'
         msg = msg + 'Показывать, что отвечает бот?'
         await self.send_message_to_user(from_user_id,
                                         msg.strip(),
                                         buttons=self.cmd_to_btns(
                                             {
                                                 '0': 'нет',
                                                 '1': 'да',
                                             }, 2),
                                         do_set_next=False)
     elif self.setup_step == 6:
         msg = '**Шаг 5**\n\n'
         msg = msg + 'После сообщения позволить боту продолжить диалог?'
         await self.send_message_to_user(from_user_id,
                                         msg.strip(),
                                         buttons=self.cmd_to_btns(
                                             {
                                                 '0': 'нет',
                                                 '1': 'да',
                                             }, 2),
                                         do_set_next=False)
     elif self.setup_step == 7:
         msg = '**Шаг 6**\n\n'
         msg = msg + 'Ну и наконец, введите текст сообщения.\n'
         msg = msg + 'Тире или 0 - использовать стандартное сообщение.\n'
         msg = msg + 'Время в формате 21:55 - использовать стандартное с уведомлением о времени прибытия.\n'
         msg = msg + 'Кроме того в тексте можно использовать следующие коды:\n'
         msg = msg + '[username] - подстановка имени пользователя для которого настраивается автоответчик.\n'
         msg = msg + '[statistics] - статистика активности и прогноз времени прибытия.\n'
         await self.send_message_to_user(
             from_user_id,
             msg.strip(),
             buttons=self.cmd_to_btns({
                 '0': 'стандартное сообщение',
             }, 2),
             do_set_next=False)
     elif self.setup_step == 8:
         msg = '**Настройка завершена!!!**\n\n'
         self.aa_options['notify_entity_id'] = from_user_id
         self.reset_aa()
         self.reset_user_setup()
         self.aa_options['is_set'] = True
         await self.send_message_to_user(from_user_id, msg.strip())
     elif self.setup_step == 200:
         msg = '**Настройка даты/времени прибытия**\n\n'
         msg = msg + 'оно будет указано ботом в начальном сообщении вида:\n'
         msg = msg + '```' + MainHelper().get_config_value(
             'chat_bot', 'bot_aa_default_message_time') + '```\n'
         msg = msg + 'Введите дату/время'
         await self.send_message_to_user(from_user_id,
                                         msg.strip(),
                                         do_set_next=False)
Ejemplo n.º 10
0
 async def init_bot_entity(self):
     if not self.bot_entity:
         self.bot_entity = await self.get_entity(
             MainHelper().get_config_value('tg_bot', 'bot_username'))
         self.bot_entity_id = self.bot_entity.id
         print('Bot entity ID: {}'.format(self.bot_entity_id))
Ejemplo n.º 11
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()
Ejemplo n.º 12
0
 def __init__(self, tg_client):
     super().__init__(self, None, None)
     self.tg_client = tg_client
     self.entity_controller = tg_client.entity_controller
     self.bot_answer_format_text = str(MainHelper().get_config_value('chat_bot', 'bot_answer_format'))
     self.users = {}
     self.right_levels = {
         '0': 'all',
         '1': 'contacts',
         '2': 'mutual contacts',
         '3': 'pre selected',
         '4': 'only me'
     }
     self.max_commands = 5
     self.commands.update({
         '/start': {
             'cmd': self.cmd_start,
             'places': ['bot'],
             'rights_level': 0,
             'desc': None
         },
         '/exit': {
             'cmd': self.cmd_exit,
             'places': ['dialog'],
             'rights_level': 0,
             'desc': 'конец диалога'
         },
         '/insta_check': {
             'class': InstaBranch,
             'places': ['bot'],
             'bot_button': {
                 'title': 'Инстаграм',
                 'position': [1, 0],
             },
             'rights_level': 0,
             'desc': 'управление скриптом для работы с инстаграмом.'
         },
         '/auto': {
             'class': AutoAnswers,
             'places': ['bot'],
             'bot_button': {
                 'title': 'Автоответчик',
                 'position': [2, 0],
             },
             'rights_level': 3,
             'desc': 'автоответчик - начальная настройка или изменение настроек.',
         },
         '/tools': {
             'class': ToolsBranch,
             'places': ['bot'],
             'bot_button': {
                 'title': 'Утилиты',
                 'position': [3, 0],
             },
             'rights_level': 1,
             'desc': 'всякие разные утилиты.'
         },
         '/user_dialogue_info': {
             'class': DialogueBranch,
             'places': ['bot', 'dialog'],
             'bot_button': {
                 'title': 'Диалоги',
                 'position': [4, 0],
             },
             'rights_level': 2,
             'desc': 'статистика диалогов с пользователем [me_user].'
         },
         '/user_activity_info': {
             'class': ActivityBranch,
             'places': ['bot', 'dialog'],
             'bot_button': {
                 'title': 'Активность пользователей',
                 'position': [4, 1],
             },
             'rights_level': 2,
             'desc': 'статистика активности пользователей - графики и листинги.'
         },
     })
     self.on_init_finish()
Ejemplo n.º 13
0
    def show_plot(self, plot_data, days_count, result_only_time, as_img=False):

        # https://plot.ly/python/renderers/

        if (days_count < 2) or result_only_time:
            fig = make_subplots(rows=2, cols=4, specs=[
                [{"colspan": 2}, None, {"colspan": 2}, None],
                [None, {"colspan": 2}, None, None]
            ])
            row2 = 1
            col2 = 3
            row3 = 2
            col3 = 2
        else:
            fig = make_subplots(rows=3, cols=6, specs=[
                [{"colspan": 6}, None, None, None, None, None],
                [{"colspan": 3}, None, None, {"colspan": 3}, None, None],
                [{"colspan": 2}, None, {"colspan": 2}, None, {"colspan": 2}, None]
            ])
            row2 = 2
            col2 = 1
            row3 = 2
            col3 = 4

        fig.update_layout(
            title_text=plot_data['title']
        )

        fig.add_trace(
            go.Bar(x=plot_data['x_full'], y=plot_data['y_time'], name="Activity time (minutes)"),
            row=1, col=1
        )
        fig.add_trace(
            go.Bar(x=plot_data['x_full'], y=plot_data['y_intervals'], name="Sessions count"),
            row=row2, col=col2
        )
        fig.add_trace(
            go.Bar(x=plot_data['x_full'], y=plot_data['y_interval_time'], name="Avg session time (minutes)"),
            row=row3, col=col3
        )

        fig.update_yaxes(title_text='Activity time', row=1, col=1)
        fig.update_yaxes(title_text='Sessions count', row=row2, col=col2)
        fig.update_yaxes(title_text='Avg session time', row=row3, col=col3)

        if (days_count >= 2) and not result_only_time:
            fig.add_trace(
                go.Bar(x=plot_data['x_days'], y=plot_data['y_days_time'], name="Days activity time (minutes)"),
                row=3, col=1
            )
            fig.update_yaxes(title_text='Activity time', row=3, col=1)

            fig.add_trace(
                go.Bar(x=plot_data['x_days'], y=plot_data['y_days_intervals'], name="Days sessions count"),
                row=3, col=3
            )
            fig.update_yaxes(title_text='Sessions count', row=3, col=3)

            fig.add_trace(
                go.Bar(x=plot_data['x_days'], y=plot_data['y_days_interval_time'], name="Days avg session time (minutes)"),
                row=3, col=5
            )
            fig.update_yaxes(title_text='Avg session time', row=3, col=5)

        # fig.update_yaxes(type="log")

        if as_img:
            if MainHelper().get_config_value('main', 'orca_path'):
                try:
                    plotly.io.orca.config.executable = MainHelper().get_config_value('main', 'orca_path')
                    fname = str(datetime.now().timestamp()) + '_' + hashlib.md5(plot_data['title'].encode('utf-8')).hexdigest()
                    fname = MainHelper().get_config_root_folder_value('main', 'files_folder') + "/" + fname + ".png"
                    fig.write_image(fname, format="png", width=1920, height=1080)
                    return fname
                except:
                    return 'Какая-то ошибка. Скорее всего некорректно настроен orca или не хватает прав на запись файла!'
            else:
                return 'Требуется сначала настроить orca!'
        else:
            fig.show()

        return ''
Ejemplo n.º 14
0
    def __init__(self, tg_bot_controller, branch_parent, branch_code=None):
        super().__init__(tg_bot_controller, branch_parent, branch_code)

        self.use_timer = False
        self.last_stories_check_time = None

        self.api = None
        self.has_insta_lib = False
        self.insta_username = None
        self.insta_password = None
        try:
            from libs.instagram_private_api import Client
            print('Instagram lib was found!')
            self.has_insta_lib = True
            self.insta_username = MainHelper().get_config_value(
                'instagram', 'username')
            self.insta_password = MainHelper().get_config_value(
                'instagram', 'password')
            self.cache_file = MainHelper().get_config_root_file_value(
                'instagram', 'cache_file')
        except ImportError:
            pass

        self.max_commands = 9
        self.commands.update({
            '/insta_check_followers': {
                'cmd':
                self.cmd_check_followers,
                'condition':
                self.can_use_branch,
                'bot_button': {
                    'title': 'Сверка подписчиков',
                    'position': [0, 0],
                },
                'places': ['bot'],
                'rights_level':
                0,
                'desc':
                'сверить списки подписчиков и подписок чтобы найти пользователей, не подписанных на вас из тех, на которых вы подписаны'
            },
            '/insta_check_followings': {
                'cmd':
                self.cmd_check_followings,
                'condition':
                self.can_use_branch,
                'bot_button': {
                    'title': 'Сверка подписок',
                    'position': [0, 1],
                },
                'places': ['bot'],
                'rights_level':
                0,
                'desc':
                'сверить списки подписчиков и подписок чтобы найти пользователей, на которых вы не подписаны из тех, что подписанных на вас'
            },
            '/insta_user_info': {
                'cmd': self.cmd_user_info,
                'condition': self.can_use_branch,
                'bot_button': {
                    'title': 'Информация',
                    'position': [1, 0],
                },
                'places': ['bot'],
                'rights_level': 0,
                'desc': 'информация о пользователе'
            },
            '/insta_user_locations': {
                'cmd': self.cmd_user_locations,
                'condition': self.can_use_branch,
                'bot_button': {
                    'title': 'Локации',
                    'position': [1, 1],
                },
                'places': ['bot'],
                'rights_level': 0,
                'desc': 'все локации, отмеченные пользователем'
            },
            '/insta_user_active_commenters': {
                'cmd': self.cmd_user_active_commenters,
                'condition': self.can_use_branch,
                'bot_button': {
                    'title': 'Активные комментаторы',
                    'position': [2, 0],
                },
                'places': ['bot'],
                'rights_level': 0,
                'desc': 'активные в комментах пользователи'
            },
            '/insta_user_active_likers': {
                'cmd': self.cmd_user_active_likers,
                'condition': self.can_use_branch,
                'bot_button': {
                    'title': 'Активные лайкеры',
                    'position': [2, 1],
                },
                'places': ['bot'],
                'rights_level': 0,
                'desc': 'активно ставящие лайки пользователи'
            },
            '/insta_stories': {
                'class':
                InstaStoriesBranch,
                'condition':
                self.can_use_branch,
                'bot_button': {
                    'title': 'Источники историй',
                    'position': [3, 0],
                },
                'places': ['bot'],
                'rights_level':
                3,
                'desc':
                'управление списками пользователей - источников stories. У этих пользователей будет проводиться регулярное выкачивание stories'
            },
            '/insta_set_username': {
                'cmd': self.cmd_set_username,
                'condition': self.can_set_username,
                'bot_button': {
                    'title': 'Указать имя',
                    'position': [3, 1],
                },
                'places': ['bot'],
                'rights_level': 0,
                'desc':
                'указать имя пользователя (чтобы каждый раз не спрашивать)'
            },
            '/insta_reset_username': {
                'cmd': self.cmd_reset_username,
                'condition': self.can_reset_username,
                'bot_button': {
                    'title': 'Сбросить имя',
                    'position': [3, 2],
                },
                'places': ['bot'],
                'rights_level': 0,
                'desc':
                'сбросить имя пользователя (чтобы каждый раз спрашивать)'
            },
        })
        self.on_init_finish()
    def save_user_stories(self, user_id, username):

        try:
            response = self.branch_parent.api.user_reel_media(user_id)
        except:
            print(username + ': Stories read error!')
            traceback.print_exc()
            return

        story_records = self.tg_bot_controller.tg_client.entity_controller.get_entity_db_option(
            0, 'insta_story_entries', True, {})

        for st_id in list(story_records.keys()):
            try:
                n_time = StatusController.now_local_datetime()
                d_time = StatusController.timestamp_to_local_datetime(
                    int(story_records[st_id]['taken_at']))
                if (not d_time) or (n_time - d_time).total_seconds() > (
                        2 * 24 * 60 * 60):
                    del story_records[st_id]
            except:
                del story_records[st_id]

        dups = 0
        for item in response['items']:
            id = item['id']
            try:
                url = item['video_versions'][0]['url']
            except KeyError:
                url = item['image_versions2']['candidates'][0]['url']
            taken_at = item['taken_at']
            location = ''
            if 'story_locations' in item:
                location_items = item['story_locations']
                if location_items and len(location_items) > 0:
                    location_item = location_items[0]
                    if location_item and ('location' in location_item
                                          ) and location_item['location']:
                        location_item = location_item['location']
                        location = location_item['name']
                        if ('address'
                                in location_item) and location_item['address']:
                            location = location + ', ' + str(
                                location_item['address'])
                        if ('city' in location_item) and location_item['city']:
                            location = location + ', ' + str(
                                location_item['city'])
                        if ('lat' in location_item) and ('lng'
                                                         in location_item):
                            location = location + ', ' + str(
                                location_item['lat']) + ',' + str(
                                    location_item['lng'])
            story_fname = self.get_story_file_name(taken_at, location)
            viewers_info = {}
            viewers_ids = []
            if 'viewers' in item:
                viewers = item['viewers']
                for viewer in viewers:
                    viewers_info[str(viewer['pk'])] = {
                        'date': datetime.now(),
                        'username': viewer['username'],
                        'full_name': viewer['full_name'],
                        'pk': viewer['pk']
                    }
                    viewers_ids.append(viewer['pk'])
                viewers_ids.sort()
                viewers = json.dumps(viewers_ids)
            else:
                viewers = '[]'

            if id not in story_records:
                entry = {
                    "id": id,
                    "url": url,
                    "userid": user_id,
                    "username": username,
                    "taken_at": taken_at,
                    "filename": "",
                    "viewers": viewers,
                    "location": location
                }
                story_records[id] = entry
                old_viewers = '[]'
                print('New story for user ' + str(username) + ' was found: ' +
                      story_fname)
                MainHelper().play_notify_sound('notify_when_new_insta_story')
            else:
                dups = dups + 1
                old_viewers = story_records[id]['viewers']

            if old_viewers != viewers:
                if viewers != '[]':
                    MainHelper().play_notify_sound(
                        'notify_when_new_insta_view')
                old_viewers = json.loads(old_viewers)
                append_strs = []

                for new_viewer in viewers_ids:
                    if new_viewer not in old_viewers:
                        new_data = viewers_info[str(new_viewer)]
                        new_str = '"' + str(new_data['pk']) + '";"' + \
                                new_data['full_name'] + '";"' + str(new_data['date'].strftime('%Y-%m-%d %H:%M:%S')) + \
                                '";"https://www.instagram.com/' + new_data['username'] + '"'
                        append_strs.append(new_str)
                        print('!!! User ' + new_data['full_name'] +
                              ' watched your story ' + story_fname)

                if len(append_strs) > 0:
                    stories_folder = MainHelper().get_config_root_folder_value(
                        'instagram', 'stories_folder')
                    if not os.path.exists(stories_folder):
                        os.makedirs(stories_folder)
                    file_path = stories_folder + "/" + str(username)
                    if not os.path.exists(file_path):
                        os.makedirs(file_path)
                    file_name = story_fname + ".csv"
                    with open(file_path + "/" + file_name, 'a') as file:
                        if len(old_viewers) == 0:
                            file.write('"ID";"Full name";"Date";"User link"' +
                                       "\n")
                        for line in append_strs:
                            file.write(line + "\n")
                        file.close()

                if id in story_records:
                    story_records[id]['viewers'] = viewers

        if dups > 0:
            if dups > 1:
                stories_str = "stories"
            else:
                stories_str = "story"
            print(username + ": " + str(dups) + " old " + stories_str +
                  " was skipped.")
        if (not response['items']) or (len(response['items']) == 0):
            print(username + ": Stories was not found.")

        self.tg_bot_controller.tg_client.entity_controller.set_entity_db_option(
            0, 'insta_story_entries', story_records, True)
    def download_stories(self):

        stories_folder = MainHelper().get_config_root_folder_value(
            'instagram', 'stories_folder')
        to_delete, to_update = [], []
        if not os.path.exists(stories_folder):
            os.makedirs(stories_folder)

        try:
            c_session = self.get_session()
        except:
            c_session = None
            print('!!! Error: Cant open session')
            traceback.print_exc()

        story_records = self.tg_bot_controller.tg_client.entity_controller.get_entity_db_option(
            0, 'insta_story_entries', True, {})

        for row in story_records.values():
            if row['filename'] and len(row['filename']) > 0:
                continue
            r = c_session.get(row['url'])
            if r.status_code == 404:
                print("Deleting old story DB record: " + str(row['id']))
                to_delete.append(row['id'])
            elif r.status_code % 200 < 100:
                if len(to_update) == 0:
                    print()
                    print("Downloading new story files:")
                file_name = self.get_story_file_name(row['taken_at'],
                                                     row['location'])
                if r.headers["Content-Type"] == "video/mp4" or r.headers[
                        "Content-Type"] == "text/plain":
                    filename = str(row['username']) + "/" + file_name + ".mp4"
                elif r.headers["Content-Type"] == "image/jpeg":
                    filename = str(row['username']) + "/" + file_name + ".jpg"
                else:
                    filename = str(
                        row['username']) + "/" + file_name + ".unknown"
                    print("WARNING: couldn't identify MIME type for URL " +
                          row['url'])
                if not os.path.exists(stories_folder + "/" +
                                      str(row['username'])):
                    os.makedirs(stories_folder + "/" + str(row['username']))
                with open(stories_folder + "/" + filename, 'wb') as f:
                    for chunk in r.iter_content(chunk_size=1024):
                        if chunk:
                            f.write(chunk)
                to_update.append([row['id'], filename])
                print(filename)

        for item in to_delete:
            if item in story_records:
                del story_records[item]

        for item in to_update:
            if item[0] in story_records:
                story_records[item[0]]['filename'] = item[1]

        self.tg_bot_controller.tg_client.entity_controller.set_entity_db_option(
            0, 'insta_story_entries', story_records, True)