예제 #1
0
 def __init__(self, server=None):
     default_server = smtp_config['servers']['default_server']
     connection_timeout = smtp_config['connection_timeout']
     self._server_to_connect_to = server if server is not None else default_server
     self.logger = Logger(
         name='EmailProvider {}'.format(self._server_to_connect_to))
     self.logger.log_string(
         LogClass.Info,
         'Attempting to connect to {}'.format(self._server_to_connect_to))
     try:
         self._smtp = smtplib.SMTP(
             host=self._server_to_connect_to['address'],
             port=self._server_to_connect_to['port'],
             timeout=connection_timeout)
         self._smtp.ehlo()
     except smtplib.SMTPException:
         error_msg = 'Failed to establish connection to {} in {} seconds.'.format(
             self._server_to_connect_to, connection_timeout)
         self.logger.log_string(LogClass.Exception, error_msg)
         raise Failure(error_msg)
     self.logger.log_string(LogClass.Info, 'Starting TLS encryption')
     response, reply = self._smtp.starttls()
     self.logger.log_string(
         LogClass.Info,
         'Got {}: {} response from server.'.format(response, reply))
     if 220 != response:
         error_msg = 'Failed to start TLS on {}'.format(
             self._server_to_connect_to)
         self.logger.log_string(LogClass.Exception, error_msg)
         raise Failure(error_msg)
class URLValidator:
    def __init__(self):
        self.logger = Logger(name='URL Validator',
                             log_name='url_validator',
                             log_to_file=True,
                             log_script_information=True,
                             log_class=LogClass.Info)

    def validate_url(self, url, use_head=False):
        self.logger.log_string(LogClass.Info, 'Validation URL {}'.format(url))
        try:
            if not use_head:
                resp = requests.get(url)
            else:
                resp = requests.head(url)
            log_string = 'Status code: {}\nHeaders: {}'.format(
                resp.status_code, resp.headers)
            self.logger.log_string(
                LogClass.Trace,
                'Got response from {}: {}'.format(url, log_string))
            if resp.status_code / 100 < 4:
                self.logger.log_string(LogClass.Info,
                                       'URL {} valid.'.format(url))
                return True
            else:
                self.logger.log_string(LogClass.Info,
                                       'URL {} invalid.'.format(url))
                return False
        except BaseException as e:
            error_msg = 'Error {} occurred during URL {} validation.'.format(
                e, url)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)
예제 #3
0
 def __init__(self, vk_api):
     self._vk_api = vk_api
     self._db_provider = BotDatabase()
     query_result = self._db_provider.get_all_domains()
     self._monitored_domains = []
     for domain in query_result:
         self._monitored_domains.append(*domain)
     self.logger = Logger(name='VK Logger')
     self._pause_monitoring = Event()
     self._stop_monitoring = Event()
     self._updates_queue = queue.Queue()
     self._url_validator = URLValidator()
예제 #4
0
    def __init__(self):
        self.bot = telebot.TeleBot(config.token)
        self.bot_logger = Logger(name='Bot logger', log_class=LogClass.Info, log_to_file=True,
                                 log_script_information=True,
                                 log_name='bot_log.txt')

        @self.bot.message_handler(content_types=['text'])
        def handle_messages(message):
            self.bot_logger.log_string(LogClass.Trace, 'Got message at {}: {}'.format(message.chat.id, message.text))
            self.bot.send_message(message.chat.id, message.text)
            log_string = 'Sent message: {message_to_send}'.format(message_to_send=message.text)
            self.bot_logger.log_string(LogClass.Info, log_string)
예제 #5
0
 def __init__(self, custom_login=None, custom_password=None, token=None, use_token=True):
     self.logger = Logger(name='VK Logger')
     self._password = vk_config['password'] if custom_password is None else custom_password
     self._login = vk_config['login'] if custom_login is None else custom_login
     self._token = token if token is not None else vk_config['api_key']
     self.logger.log_string(LogClass.Trace, "Attempting to perform authentication with {}".format(
         self._login if not use_token else 'token'))
     if use_token:
         self._authenticate(token=self._token)
     else:
         self._authenticate(self._login, self._password)
     self.logger.log_string(LogClass.Info,
                            "Authentication with {} successful.".format(self._login if not use_token else 'token'))
예제 #6
0
class VkModule:
    """Module used to provide access to Vk and return API"""
    def __init__(self, custom_login=None, custom_password=None, token=None, use_token=True):
        self.logger = Logger(name='VK Logger')
        self._password = vk_config['password'] if custom_password is None else custom_password
        self._login = vk_config['login'] if custom_login is None else custom_login
        self._token = token if token is not None else vk_config['api_key']
        self.logger.log_string(LogClass.Trace, "Attempting to perform authentication with {}".format(
            self._login if not use_token else 'token'))
        if use_token:
            self._authenticate(token=self._token)
        else:
            self._authenticate(self._login, self._password)
        self.logger.log_string(LogClass.Info,
                               "Authentication with {} successful.".format(self._login if not use_token else 'token'))

    def _auth_handler(self):
        # Called when two-factor auth is needed
        self.logger.log_string(LogClass.Warning, "Two-factor authentication confirmation required!")
        key = input("Enter authentication code: ")
        remember_device = True
        return key, remember_device

    def _authenticate(self, login=None, password=None, token=None):
        vk_session = vk_api.VkApi(login=login, password=password,
                                  auth_handler=self._auth_handler) if token is None else vk_api.VkApi(token=token)
        try:
            if token is None:
                vk_session.auth()
        except vk_api.AuthError as e:
            error_string = "Exception {} occurred during authentication in VK with {}.".format(e,
                                                                                               self._login if token is None else token)
            self.logger.log_string(LogClass.Exception, error_string)
            raise Failure(error_string)
        self.api = vk_session.get_api()
예제 #7
0
 def __init__(self, database, logger=None):
     self.logger = Logger(
         name='DatabaseLogger',
         log_class=LogClass.Info,
         log_script_information=True,
         log_to_file=True,
         log_name='database_log.txt') if logger is None else logger
     self.logger.log_string(LogClass.Info,
                            'Attempting to connect to {}'.format(database))
     try:
         self._connection = sqlite3.connect(database)
     except BaseException as e:
         self.logger.log_string(
             LogClass.Exception,
             '{} occurred during connection to a {} database'.format(
                 e, database))
     self._cursor = self._connection.cursor()
예제 #8
0
class DataBase:
    def __init__(self, database, logger=None):
        self.logger = Logger(
            name='DatabaseLogger',
            log_class=LogClass.Info,
            log_script_information=True,
            log_to_file=True,
            log_name='database_log.txt') if logger is None else logger
        self.logger.log_string(LogClass.Info,
                               'Attempting to connect to {}'.format(database))
        try:
            self._connection = sqlite3.connect(database)
        except BaseException as e:
            self.logger.log_string(
                LogClass.Exception,
                '{} occurred during connection to a {} database'.format(
                    e, database))
        self._cursor = self._connection.cursor()

    def stop(self):
        self._connection.close()

    def execute_command(self, command, params=None):
        log_string = 'Executing {} with {} parameters'.format(command, params)
        self.logger.log_string(LogClass.Info, log_string)
        if params is None:
            self._cursor.execute(command)
        else:
            self._cursor.execute(command, params)

    def backup_database(self):
        pass

    def restore_last_working_state(self):
        pass

    def commit_chages(self):
        self.logger.log_string(LogClass.Trace, 'Chages to database saved')
        self._connection.commit()
예제 #9
0
class VkWallMonitor:
    """
    Class used to monitor wall activities on desired domains.
    """
    def __init__(self, vk_api):
        self._vk_api = vk_api
        self._db_provider = BotDatabase()
        query_result = self._db_provider.get_all_domains()
        self._monitored_domains = []
        for domain in query_result:
            self._monitored_domains.append(*domain)
        self.logger = Logger(name='VK Logger')
        self._pause_monitoring = Event()
        self._stop_monitoring = Event()
        self._updates_queue = queue.Queue()
        self._url_validator = URLValidator()

    def add_domain(self, domain):
        vk_url = 'https://vk.com/' + domain
        if self._url_validator.validate_url(vk_url):
            if not domain in self._monitored_domains:
                self._monitored_domains.append(domain)
                self._db_provider.add_domain(domain)
                self.monitor_wall(domain)
        else:
            self.logger.log_string(LogClass.Info,
                                   'Invalid domain {} entered!'.format(domain))

    def get_last_wall_post(self, owner_id=0, domain=None, **kwargs):
        return self.get_n_last_wall_posts(owner_id, domain, 1, **kwargs)[0]

    def get_n_last_wall_posts(self,
                              owner_id=0,
                              domain=None,
                              count=1,
                              **kwargs):
        destination = 'destination {}, with {}'.format(
            owner_id if domain is None else domain, kwargs.keys())
        self.logger.log_string(
            LogClass.Info,
            "Sending 'get wall posts' request to {}".format(destination))
        if domain is None:
            response = self._vk_api.wall.get(owner_id=owner_id,
                                             count=count,
                                             **kwargs)
        else:
            response = self._vk_api.wall.get(domain=domain,
                                             count=count,
                                             **kwargs)
        self.logger.log_string(
            LogClass.Info,
            "Got response from {}".format(destination, response))
        if response['items']:
            return response['items']
        else:
            message = 'Something gone wrong during request to {}.'.format(
                destination)
            self.logger.log_string(LogClass.Exception, message)
            raise Failure(message)

    def run_monitor_thread(self, domain):
        t = Thread(target=self.monitor_wall, args=domain, daemon=True)
        t.start()

    def monitor_wall(self, domain):
        # TODO: Продумать структуру класса...
        self.logger.log_string(LogClass.Info,
                               'Starting monitoring of {}'.format(domain))
        # Setup
        last_posts_id = []
        last_20_posts = self.get_n_last_wall_posts(domain=domain, count=20)
        for post in last_20_posts:
            last_posts_id.append(post['id'])
        while not self._stop_monitoring.isSet:
            while not self._pause_monitoring.isSet and not self._stop_monitoring.isSet:
                time.sleep(60)
                last_posts = self.get_n_last_wall_posts(domain=domain,
                                                        count=10)
                for post in last_posts:
                    if not post['id'] in last_posts_id:
                        self._updates_queue.put({domain: post})
                        last_posts_id.append(post['id'])

    def pause_monitoring(self):
        self.logger.log_string(LogClass.Info,
                               'Monitoring of vk wall posts is paused.')
        if not self._pause_monitoring.isSet:
            self._pause_monitoring.set()

    def resume_monitoring(self):
        if self._pause_monitoring.isSet():
            self.logger.log_string(LogClass.Info,
                                   'Monitoring of vk wall posts continued.')
            self._pause_monitoring.clear()

    def stop_monitoring(self):
        self._stop_monitoring.set()
예제 #10
0
 def __init__(self):
     self.logger = Logger(name='URL Validator',
                          log_name='url_validator',
                          log_to_file=True,
                          log_script_information=True,
                          log_class=LogClass.Info)
예제 #11
0
    def __init__(self):
        self.bot = telebot.TeleBot(config.token)
        self.bot_logger = Logger(name='Bot logger',
                                 log_class=LogClass.Info,
                                 log_to_file=True,
                                 log_script_information=True,
                                 log_name='bot_log.txt')
        self.vk = VkModule()
        self.vk_wall_monitor = VkWallMonitor(self.vk.api)
        self.monitor_posts = {}
        self.OWM_provider = OWMProvider()

        @self.bot.message_handler(commands=['weather'])
        def handle_weather(message):
            try:
                self.bot_logger.log_string(
                    LogClass.Info,
                    f'Got message from {message.chat.id}: {message}')
                message_string = str(message.text).lower()
                city = message_string.split(' ')[1]
                weather = self.OWM_provider.get_current_weather_in_city(city)
                if weather is not None:
                    message_to_send = 'Текущая погода: {}\nТемпература: {} град. цельсия\nДавление: {} мм.рт.ст.\n' \
                                      'Влажность: {}\nВосход: {}\nЗакат: {}\nВетер: {} м/c'.format(
                        weather.description, weather.temp, weather.pressure,
                        weather.humidity, weather.sunrise, weather.sunset, weather.wind)
                else:
                    message_to_send = 'Возникла ошибка, соси хуй!'
                self.bot.send_message(message.chat.id, message_to_send)
                log_string = 'Sent message: {message_to_send}'.format(
                    message_to_send=message_to_send)
                self.bot_logger.log_string(LogClass.Info, log_string)
            except BaseException as e:
                self.bot_logger.log_string(
                    LogClass.Exception,
                    'Возникла ошибка при обработке погоды'.format(e))

        @self.bot.message_handler(commands=['monitor', 'off_monitor'])
        def handle_monitoring(message):
            try:
                self.bot_logger.log_string(
                    LogClass.Info,
                    f'Got message from {message.chat.id}: {message}')
                message_string = str(message.text).lower()
                try:
                    target = message_string.split(' ')[1]
                except BaseException:
                    message_to_send = 'Используйте формат /команда домен\nДомен-короткое имя страницы - цели.'
                    self.bot.send_message(message.chat.id, message_to_send)
                    raise Failure(
                        'Невозможно получить домен из сообщения {}'.format(
                            message.text))
                if message_string.__contains__('/off_monitor'):
                    self.stop_monitoring_posts(target, message.chat.id)
                    message_to_send = 'Прекращён мониторинг постов со страницы {}'.format(
                        target)
                else:
                    self.start_last_wall_posts_monitoring(
                        target, message.chat.id)
                    message_to_send = 'Начинаем мониторинг постов в {}\nПоследние 5 постов:\n'.format(
                        target)
                self.bot.send_message(message.chat.id, message_to_send)
                log_string = 'Sent message: {message_to_send}'.format(
                    message_to_send=message_to_send)
                self.bot_logger.log_string(LogClass.Info, log_string)
            except BaseException as e:
                self.bot_logger.log_string(LogClass.Exception,
                                           f'{e} occurred.')

        @self.bot.message_handler(content_types=['text'])
        def handle_messages(message):
            self.bot_logger.log_string(
                LogClass.Trace,
                'Got message at {}: {}'.format(message.chat.id, message.text))
예제 #12
0
class TelegramBot:
    def __init__(self):
        self.bot = telebot.TeleBot(config.token)
        self.bot_logger = Logger(name='Bot logger',
                                 log_class=LogClass.Info,
                                 log_to_file=True,
                                 log_script_information=True,
                                 log_name='bot_log.txt')
        self.vk = VkModule()
        self.vk_wall_monitor = VkWallMonitor(self.vk.api)
        self.monitor_posts = {}
        self.OWM_provider = OWMProvider()

        @self.bot.message_handler(commands=['weather'])
        def handle_weather(message):
            try:
                self.bot_logger.log_string(
                    LogClass.Info,
                    f'Got message from {message.chat.id}: {message}')
                message_string = str(message.text).lower()
                city = message_string.split(' ')[1]
                weather = self.OWM_provider.get_current_weather_in_city(city)
                if weather is not None:
                    message_to_send = 'Текущая погода: {}\nТемпература: {} град. цельсия\nДавление: {} мм.рт.ст.\n' \
                                      'Влажность: {}\nВосход: {}\nЗакат: {}\nВетер: {} м/c'.format(
                        weather.description, weather.temp, weather.pressure,
                        weather.humidity, weather.sunrise, weather.sunset, weather.wind)
                else:
                    message_to_send = 'Возникла ошибка, соси хуй!'
                self.bot.send_message(message.chat.id, message_to_send)
                log_string = 'Sent message: {message_to_send}'.format(
                    message_to_send=message_to_send)
                self.bot_logger.log_string(LogClass.Info, log_string)
            except BaseException as e:
                self.bot_logger.log_string(
                    LogClass.Exception,
                    'Возникла ошибка при обработке погоды'.format(e))

        @self.bot.message_handler(commands=['monitor', 'off_monitor'])
        def handle_monitoring(message):
            try:
                self.bot_logger.log_string(
                    LogClass.Info,
                    f'Got message from {message.chat.id}: {message}')
                message_string = str(message.text).lower()
                try:
                    target = message_string.split(' ')[1]
                except BaseException:
                    message_to_send = 'Используйте формат /команда домен\nДомен-короткое имя страницы - цели.'
                    self.bot.send_message(message.chat.id, message_to_send)
                    raise Failure(
                        'Невозможно получить домен из сообщения {}'.format(
                            message.text))
                if message_string.__contains__('/off_monitor'):
                    self.stop_monitoring_posts(target, message.chat.id)
                    message_to_send = 'Прекращён мониторинг постов со страницы {}'.format(
                        target)
                else:
                    self.start_last_wall_posts_monitoring(
                        target, message.chat.id)
                    message_to_send = 'Начинаем мониторинг постов в {}\nПоследние 5 постов:\n'.format(
                        target)
                self.bot.send_message(message.chat.id, message_to_send)
                log_string = 'Sent message: {message_to_send}'.format(
                    message_to_send=message_to_send)
                self.bot_logger.log_string(LogClass.Info, log_string)
            except BaseException as e:
                self.bot_logger.log_string(LogClass.Exception,
                                           f'{e} occurred.')

        @self.bot.message_handler(content_types=['text'])
        def handle_messages(message):
            self.bot_logger.log_string(
                LogClass.Trace,
                'Got message at {}: {}'.format(message.chat.id, message.text))
            # self.bot.send_message(message.chat.id, message.text)
            # log_string = 'Sent message: {message_to_send}'.format(message_to_send=message.text)
            # self.bot_logger.log_string(LogClass.Info, log_string)

    def monitor_wall_posts(self, domain, chat_id):
        try:
            last_posts_ids = []
            while self.monitor_posts[(domain, chat_id)].isSet():
                five_last_posts = self.vk_wall_monitor.get_n_last_wall_posts(
                    domain=domain, count=5)
                for post in five_last_posts:
                    if not post['id'] in last_posts_ids:
                        self.bot.send_message(
                            chat_id, "Новый пост на странице {}:\n{}".format(
                                domain, post['text']))
                        last_posts_ids.append(post['id'])
                sleep(60)
                if len(last_posts_ids) > 50:
                    last_posts_ids = last_posts_ids[:50]
        except:
            self.monitor_posts.pop((domain, chat_id))

    def start_last_wall_posts_monitoring(self, domain, chat_id):
        if not (domain, chat_id) in self.monitor_posts.keys():
            self.monitor_posts[(domain, chat_id)] = Event()
        if not self.monitor_posts[(domain, chat_id)].isSet():
            self.monitor_posts[(domain, chat_id)].set()
            t = Thread(target=self.monitor_wall_posts, args=(domain, chat_id))
            t.setDaemon(True)
            t.start()

    def stop_monitoring_posts(self, domain, chat_id):
        self.monitor_posts[(domain, chat_id)].clear()

    def start_bot(self):
        self.bot.polling(none_stop=True)

    def stop_bot(self):
        self.bot.stop_polling()
예제 #13
0
class EMailProvider:
    def __init__(self, server=None):
        default_server = smtp_config['servers']['default_server']
        connection_timeout = smtp_config['connection_timeout']
        self._server_to_connect_to = server if server is not None else default_server
        self.logger = Logger(
            name='EmailProvider {}'.format(self._server_to_connect_to))
        self.logger.log_string(
            LogClass.Info,
            'Attempting to connect to {}'.format(self._server_to_connect_to))
        try:
            self._smtp = smtplib.SMTP(
                host=self._server_to_connect_to['address'],
                port=self._server_to_connect_to['port'],
                timeout=connection_timeout)
            self._smtp.ehlo()
        except smtplib.SMTPException:
            error_msg = 'Failed to establish connection to {} in {} seconds.'.format(
                self._server_to_connect_to, connection_timeout)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)
        self.logger.log_string(LogClass.Info, 'Starting TLS encryption')
        response, reply = self._smtp.starttls()
        self.logger.log_string(
            LogClass.Info,
            'Got {}: {} response from server.'.format(response, reply))
        if 220 != response:
            error_msg = 'Failed to start TLS on {}'.format(
                self._server_to_connect_to)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)

    def authorize(self, email, password):
        self.logger.log_string(
            LogClass.Info, 'Attempting login to {} for user {}'.format(
                self._server_to_connect_to, email))
        try:
            self._smtp.login(user=email, password=password)
        except smtplib.SMTPException:
            error_msg = 'Failed to authorize to {} for user {}'.format(
                self._server_to_connect_to, email)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)
        self.logger.log_string(
            LogClass.Info,
            'Authorized {} on {}'.format(email, self._server_to_connect_to))

    def send_email(self, from_addr, to_addr, message, subject=None):
        if subject is not None:
            message_to_send = 'Subject: {}\n\n{}'.format(subject, message)
        else:
            message_to_send = message
        self.logger.log_string(
            LogClass.Info,
            'Attempting to send mail: {} from {} to {} on {}'.format(
                message_to_send, from_addr, to_addr,
                self._server_to_connect_to))
        try:
            self._smtp.sendmail(from_addr, to_addr, message_to_send.encode())
        except smtplib.SMTPException:
            error_msg = 'Failed to send message from {} to {} on {}'.format(
                from_addr, to_addr, self._server_to_connect_to)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)
        self.logger.log_string(
            LogClass.Info, 'Message from {} to {} sent on {}'.format(
                from_addr, to_addr, self._server_to_connect_to))

    def stop(self):
        self._smtp.quit()
예제 #14
0
 def __init__(self, database=None):
     database_path = database if database is not None else os.path.join(
         DATABASE_PATH, cfg.public['databases']['default_db'])
     self.logger = Logger(name='DatabaseLogger', log_name='BotDatabase_log')
     super().__init__(database_path, self.logger)
예제 #15
0
class BotDatabase(DataBase):
    def __init__(self, database=None):
        database_path = database if database is not None else os.path.join(
            DATABASE_PATH, cfg.public['databases']['default_db'])
        self.logger = Logger(name='DatabaseLogger', log_name='BotDatabase_log')
        super().__init__(database_path, self.logger)

    def check_if_chat_not_in_database(self, chat_id):
        return self._cursor.execute('SELECT * FROM chats WHERE id_chat = ?',
                                    (chat_id, )).fetchone() is None

    def get_city_id_by_name(self, city):
        id_city = self._cursor.execute('SELECT id FROM cities WHERE name=?',
                                       (city, )).fetchone()
        return id_city[0] if id_city is not None else id_city

    def get_wall_id_by_domain(self, domain):
        id_wall = self._cursor.execute(
            'SELECT id FROM vk_walls WHERE domain=?', (domain, )).fetchone()
        return id_wall[0] if id_wall is not None else id_wall

    def get_weather_subscriptions(self, chat_id):
        return self._cursor.execute(
            'SELECT * FROM weather_subscriptions WHERE id_chat=?',
            (chat_id, )).fetchall()

    def get_vk_subscriptions_by_chat_id(self, chat_id):
        return self._cursor.execute(
            'SELECT id_domain FROM vk_wall_subscriptions WHERE id_chat=?',
            (chat_id, )).fetchall()

    def get_chats_subscribed_to_domain(self, domain):
        return self._cursor.execute(
            'SELECT id_chat FROM vk_wall_subscriptions WHERE id_domain=?',
            (self.get_wall_id_by_domain(domain), )).fetchall()

    def get_domain_by_id(self, domain_id):
        id_domain = self._cursor.execute(
            'SELECT domain FROM vk_walls WHERE id=?',
            (domain_id, )).fetchone()
        return id_domain[0] if id_domain is not None else id_domain

    def get_city_by_id(self, city_id):
        city = self._cursor.execute('SELECT name FROM cities WHERE id=?',
                                    (city_id, )).fetchone()
        return city[0] if city is not None else city

    def add_weather_subscription(self, chat_id, city):
        self.logger.log_string(
            LogClass.Trace,
            'Attempting to add chat {} subscription on {} to table weather_subscriptions.'
            .format(chat_id, city))
        try:
            if self.check_if_chat_not_in_database(chat_id):
                self.add_chat(chat_id)
            query_result = self.get_city_id_by_name(city)
            if query_result is None:
                self.add_city(city)
                query_result = self.get_city_id_by_name(city)
            weather_subscription_query_result = self._cursor.execute(
                'SELECT * FROM weather_subscriptions WHERE id_chat=? AND id_city=?',
                (chat_id, query_result))
            if weather_subscription_query_result.fetchone() is None:
                self._cursor.execute(
                    'INSERT INTO weather_subscriptions(id_chat, id_city) VALUES (?,?)',
                    (chat_id, query_result))
                self.commit_chages()
                self.logger.log_string(
                    LogClass.Trace,
                    'Chat {} successfully subscribed to weather in {}.'.format(
                        chat_id, city))
        except BaseException as e:
            error_msg = 'Error {} during adding chat {} weather subscription on {} to database.'.format(
                e, chat_id, city)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)

    def add_chat(self, chat_id):
        self.logger.log_string(
            LogClass.Trace,
            'Attempting to add chat {} to table chats.'.format(chat_id))
        try:
            query_result = self._cursor.execute(
                'SELECT * FROM chats WHERE id_chat=?', (chat_id, )).fetchone()
            if query_result is None:
                self._cursor.execute('INSERT INTO chats(id_chat) VALUES (?)',
                                     (chat_id, ))
                self.commit_chages()
                self.logger.log_string(
                    LogClass.Trace,
                    'Chat {} successfully added to database.'.format(chat_id))
            else:
                self.logger.log_string(
                    LogClass.Trace,
                    'Chat {} already in database'.format(chat_id))
        except BaseException as e:
            error_msg = 'Error {} during adding chat {} to database.'.format(
                e, chat_id)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)

    def add_city(self, city):
        self.logger.log_string(
            LogClass.Trace, 'Attempting add {} to table cities'.format(city))
        try:
            if self.get_city_id_by_name(city) is None:
                self._cursor.execute('INSERT INTO cities(name) VALUES (?)',
                                     (city, ))
                self.commit_chages()
                self.logger.log_string(
                    LogClass.Trace,
                    'City {} successfully added to database.'.format(city))
            else:
                self.logger.log_string(
                    LogClass.Trace,
                    'City {} already exists in database'.format(city))
        except BaseException as e:
            error_msg = 'Error {} during adding city {} to table cities'.format(
                e, city)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)

    def add_vk_domain_subscription(self, chat_id, domain):
        self.logger.log_string(
            LogClass.Trace,
            'Attempting to add chat {} subscription on {} to table vk_walls_subscription.'
            .format(chat_id, domain))
        try:
            if self.check_if_chat_not_in_database(chat_id):
                self.add_chat(chat_id)
            query_result = self.get_wall_id_by_domain(domain)
            if query_result is None:
                self.add_domain(domain)
                query_result = self.get_wall_id_by_domain(domain)
            subscription_query_result = self._cursor.execute(
                'SELECT * FROM vk_wall_subscriptions WHERE id_chat=? AND id_domain=?',
                (chat_id, query_result)).fetchone()
            if subscription_query_result is None:
                self._cursor.execute(
                    'INSERT INTO vk_wall_subscriptions(id_chat, id_domain) VALUES (?,?)',
                    (chat_id, query_result))
                self.commit_chages()
                self.logger.log_string(
                    LogClass.Trace,
                    'Chat {} successfully subscribed to wall {}.'.format(
                        chat_id, domain))
        except BaseException as e:
            error_msg = 'Error {} during adding chat {} subscription on {} to database.'.format(
                e, chat_id, domain)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)

    def remove_city(self, city):
        self.logger.log_string(
            LogClass.Trace,
            'Attempting deletion of {} city from cities'.format(city))
        try:
            self._cursor.execute('DELETE FROM cities WHERE name=?', (city, ))
            self.commit_chages()
            self.logger.log_string(
                LogClass.Trace,
                'City {} successfully removed from database.'.format(city))
        except BaseException as e:
            error_msg = 'Error {} occurred during deleting {} from cities'.format(
                e, city)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)

    def add_domain(self, domain):
        self.logger.log_string(
            LogClass.Trace,
            'Attempting add {} to table vk_walls'.format(domain))
        try:
            if self.get_wall_id_by_domain(domain) is None:
                self._cursor.execute('INSERT INTO vk_walls(domain) VALUES (?)',
                                     (domain, ))
                self.commit_chages()
                self.logger.log_string(
                    LogClass.Trace,
                    'Domain {} successfully added to database.'.format(domain))
            else:
                self.logger.log_string(
                    LogClass.Trace,
                    'Domain {} already in database'.format(domain))
        except BaseException as e:
            error_msg = 'Error {} during adding domain {} to table vk_walls'.format(
                e, domain)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)

    def remove_domain(self, domain):
        self.logger.log_string(
            LogClass.Trace,
            'Attempting deletion of {} domain from vk_walls'.format(domain))
        try:
            self._cursor.execute('DELETE FROM vk_walls WHERE domain=?',
                                 (domain, ))
            self.commit_chages()
            self.logger.log_string(
                LogClass.Trace,
                'Domain {} successfully removed from database.'.format(domain))
        except BaseException as e:
            error_msg = 'Error {} occurred during deleting {} from vk_walls'.format(
                e, domain)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)

    def remove_vk_domain_subscription(self, chat_id, domain):
        self.logger.log_string(
            LogClass.Trace,
            'Attempting deletion of {} subscription to {} from vk_walls_subscriptions'
            .format(chat_id, domain))
        try:
            domain_id = self.get_wall_id_by_domain(domain)
            self._cursor.execute(
                'DELETE FROM vk_wall_subscriptions WHERE id_chat=? AND id_domain=?',
                (chat_id, domain_id))
            self.commit_chages()
            self.logger.log_string(
                LogClass.Trace,
                'Subscription {} to {} successfully removed from database.'.
                format(chat_id, domain))
        except BaseException as e:
            error_msg = 'Error {} occurred during deletion of {} subscription to {} from vk_walls_subscriptions'.format(
                e, chat_id, domain)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)

    def remove_weather_subscription(self, chat_id, city):
        self.logger.log_string(
            LogClass.Trace,
            'Attempting deletion of {} subscription to weather {} from weather_subscriptions'
            .format(chat_id, city))
        try:
            city_id = self.get_city_id_by_name(city)
            self._cursor.execute(
                'DELETE FROM weather_subscriptions WHERE id_chat=? AND id_city=?',
                (chat_id, city_id))
            self.commit_chages()
            self.logger.log_string(
                LogClass.Trace,
                'Subscription {} to weather in {} successfully removed from database.'
                .format(chat_id, city))
        except BaseException as e:
            error_msg = 'Error {} occurred during deletion of {} subscription to weather in {} from weather_subscriptions'.format(
                e, chat_id, city)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)

    def get_all_domains(self):
        self.logger.log_string(LogClass.Trace,
                               'Attempting to get all domains from database')
        try:
            query_result = self._cursor.execute('SELECT domain FROM vk_walls')
        except BaseException as e:
            error_msg = 'Failed to get all domains from vk_walls, {} occurred'.format(
                e)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)
        return query_result.fetchall()

    def get_all_cities(self):
        self.logger.log_string(LogClass.Trace,
                               'Attempting to get all domains from database')
        try:
            query_result = self._cursor.execute('SELECT name FROM cities')
        except BaseException as e:
            error_msg = 'Failed to get all cities, {} occurred'.format(e)
            self.logger.log_string(LogClass.Exception, error_msg)
            raise Failure(error_msg)
        return query_result.fetchall()
예제 #16
0
 def __init__(self):
     self.logger = Logger(name='VK logger')
     self._updates_queue = Queue()
     self._domain_monitor_controllers = {}