Exemple #1
0
def get_bool_key(name, required=False):
    if name in DEFAULTS:
        default = DEFAULTS[name]
    else:
        default = None
    if not (data := env.bool(name, default=default)) and not required:
        log.warn('No bool key: ' + name)
        return False
Exemple #2
0
def get_list_key(name, required=False):
    if name in DEFAULTS:
        default = DEFAULTS[name]
    else:
        default = None
    if not (data := env.list(name, default=default)) and not required:
        log.warn('No list key: ' + name)
        return []
Exemple #3
0
def get_str_key(name, required=False):
    if name in DEFAULTS:
        default = DEFAULTS[name]
    else:
        default = None
    if not (data := env.str(name, default=default)) and not required:
        log.warn('No str key: ' + name)
        return None
Exemple #4
0
async def all_errors_handler(update: Update, error):
    if update.message is not None:
        message = update.message
    elif update.callback_query is not None:
        message = update.callback_query.message
    elif update.edited_message is not None:
        message = update.edited_message
    else:
        return True  # we don't want other guys in playground

    chat_id = message.chat.id
    err_tlt = sys.exc_info()[0].__name__
    err_msg = str(sys.exc_info()[1])

    log.warn('Error caused update is: \n' +
             html.escape(str(parse_update(message)), quote=False))

    if redis.get(chat_id) == str(error):
        # by err_tlt we assume that it is same error
        return True

    if err_tlt == 'BadRequest' and err_msg == 'Have no rights to send a message':
        return True

    ignored_errors = ('FloodWaitError', 'RetryAfter', 'SlowModeWaitError',
                      'InvalidQueryID')
    if err_tlt in ignored_errors:
        return True

    if err_tlt in ('NetworkError', 'TelegramAPIError', 'RestartingTelegram'):
        log.error("Conn/API error detected", exc_info=error)
        return True

    text = "<b>Sorry, I encountered a error!</b>\n"
    text += f'<code>{html.escape(err_tlt, quote=False)}: {html.escape(err_msg, quote=False)}</code>'
    redis.set(chat_id, str(error), ex=600)
    await bot.send_message(chat_id, text)
Exemple #5
0
def register(*args,
             cmds=None,
             f=None,
             allow_edited=True,
             allow_kwargs=False,
             **kwargs):
    if cmds and type(cmds) == str:
        cmds = [cmds]

    register_kwargs = {}

    if cmds and not f:
        regex = r'\A^{}('.format('[!/]' if ALLOW_COMMANDS_FROM_EXC else '/')

        if 'not_forwarded' not in kwargs and ALLOW_F_COMMANDS is False:
            kwargs['not_forwarded'] = True

        if 'cmd_not_mono' not in kwargs and CMD_NOT_MONO:
            kwargs['cmd_not_mono'] = True

        for idx, cmd in enumerate(cmds):
            if cmd in REGISTRED_COMMANDS:
                log.warn(f'Duplication of /{cmd} command')
            REGISTRED_COMMANDS.append(cmd)
            regex += cmd

            if not idx == len(cmds) - 1:
                if not cmds[0] in COMMANDS_ALIASES:
                    COMMANDS_ALIASES[cmds[0]] = [cmds[idx + 1]]
                else:
                    COMMANDS_ALIASES[cmds[0]].append(cmds[idx + 1])
                regex += "|"

        if 'disable_args' in kwargs:
            del kwargs['disable_args']
            regex += f")($|@{BOT_USERNAME}$)"
        else:
            regex += f")(|@{BOT_USERNAME})(:? |$)"

        register_kwargs['regexp'] = regex

    elif f == 'text':
        register_kwargs['content_types'] = types.ContentTypes.TEXT

    elif f == 'welcome':
        register_kwargs['content_types'] = types.ContentTypes.NEW_CHAT_MEMBERS

    elif f == 'leave':
        register_kwargs['content_types'] = types.ContentTypes.LEFT_CHAT_MEMBER

    elif f == 'service':
        register_kwargs['content_types'] = types.ContentTypes.NEW_CHAT_MEMBERS
    elif f == 'any':
        register_kwargs['content_types'] = types.ContentTypes.ANY

    log.debug(f"Registred new handler: <d><n>{str(register_kwargs)}</></>")

    register_kwargs.update(kwargs)

    def decorator(func):
        async def new_func(*def_args, **def_kwargs):
            message = def_args[0]

            if cmds:
                message.conf['cmds'] = cmds

            if allow_kwargs is False:
                def_kwargs = dict()

            if DEBUG_MODE:
                # log.debug('[*] Starting {}.'.format(func.__name__))
                # log.debug('Event: \n' + str(message))
                start = time.time()
                await func(*def_args, **def_kwargs)
                log.debug('[*] {} Time: {} sec.'.format(
                    func.__name__,
                    time.time() - start))
            else:
                await func(*def_args, **def_kwargs)
            raise SkipHandler()

        if f == 'cb':
            dp.register_callback_query_handler(new_func, *args,
                                               **register_kwargs)
        else:
            dp.register_message_handler(new_func, *args, **register_kwargs)
            if allow_edited is True:
                dp.register_edited_message_handler(new_func, *args,
                                                   **register_kwargs)

    return decorator
Exemple #6
0
from aiogram.contrib.fsm_storage.redis import RedisStorage2

from utah.config import get_str_key, get_int_key, get_list_key, get_bool_key
from utah.utils.logger import log
from utah.versions import UTAH_VERSION

log.info("----------------------")
log.info("|      Utah      |")
log.info("----------------------")
log.info("Version: " + UTAH_VERSION)

if get_bool_key("DEBUG_MODE") is True:
    UTAH_VERSION += "-debug"
    log.setLevel(logging.DEBUG)
    log.warn(
        "! Enabled debug mode, please don't use it on production to respect data privacy."
    )

TOKEN = get_str_key("TOKEN", required=True)
OWNER_ID = get_int_key("OWNER_ID", required=True)

OPERATORS = list(get_list_key("OPERATORS"))
OPERATORS.append(OWNER_ID)

# SpamWatch
spamwatch_api = get_str_key("SW_API", required=True)
sw = spamwatch.Client(spamwatch_api)

# Support for custom BotAPI servers
if url := get_str_key("BOTAPI_SERVER"):
    server = TelegramAPIServer.from_base(url)
Exemple #7
0
# This file is part of Utah (Telegram Bot)

# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

from utah.utils.logger import log

log.warn('Blank DB update, nothing to-do, skipping!')
else:
    curr_ver = data['db_ver']
    log.info("Your database structure version is: " + str(curr_ver))
    if DB_STRUCTURE_VER > curr_ver:
        log.error("Your database is old! Waiting 20 seconds till update...")
        log.info("Press CTRL + C to cancel!")
        time.sleep(20)
        log.debug("Trying to update database structure...")
        log.info("--------------------------------")
        log.info("Your current database structure version: " + str(curr_ver))
        log.info("New database structure version: " + str(DB_STRUCTURE_VER))
        log.info("--------------------------------")
        old_ver = curr_ver
        while curr_ver < DB_STRUCTURE_VER:
            new_ver = curr_ver + 1
            log.info(f"Trying update to {str(new_ver)}...")

            log.debug("Importing: texas.db." + str(new_ver))
            import_module("texas.db." + str(new_ver))

            curr_ver += 1
            mongodb.db_structure.update_one({'db_ver': curr_ver - 1}, {"$set": {'db_ver': curr_ver}})

        log.warn(f"Database update done to {str(curr_ver)} successfully!")
        log.debug("Let's notify the bot owner")
        loop = asyncio.get_event_loop()
        bot_info = loop.run_until_complete(notify_bot_owner(old_ver, curr_ver))
        log.info("Rescue normal bot startup...")
    else:
        log.debug("No database structure updates found, skipping!")