• Как правильно сделать декоратор для открытия подключения к базе данных (на основе моего кода с комментариями)?

    @Wolfengo Автор вопроса
    Я ещё зелёный, сильно не душите
    По совету из комментариев, реализовал код вот так:

    import psycopg2.pool
    from psycopg2 import errors
    
    dbname = 'mydatabase'
    user = 'postgres'
    password = '123'
    host = 'localhost'
    port = '5432'
    connection_string = f"dbname={dbname} user={user} password={password} host={host} port={port}"
    
    
    class DatabaseConnection:
        def __init__(self, connection_string):
            self._connection_string = connection_string
            self._connection_pool = psycopg2.pool.SimpleConnectionPool(minconn=1, maxconn=10, dsn=connection_string)
            self._connection = None
    
        def __enter__(self):
            self._connection = self._connection_pool.getconn()
            return self._connection.cursor()
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            if self._connection:
                self._connection.commit()
                self._connection_pool.putconn(self._connection)
    
    
    class PostgreSQLDatabase:
        def __init__(self, connection_string):
            self._connection_string = connection_string
    
        def __enter__(self):
            self._connection = DatabaseConnection(self._connection_string)
            return self._connection.__enter__()
    
        def __exit__(self, exc_type, exc_val, exc_tb):
            return self._connection.__exit__(exc_type, exc_val, exc_tb)
    
    
    class Admin_connected:
        def __init__(self):
            self.database = PostgreSQLDatabase(connection_string)
    
        def create_database_if_not_exists(self):
            # Подключаемся к базе postgres, чтобы узнать, существует ли база
            conn = psycopg2.connect(database='postgres', user=user, password=password, host=host,
                                    port=port)
            conn.autocommit = True
            cursor = conn.cursor()
    
            # Проверка наличия базы данных
            cursor.execute("SELECT 1 FROM pg_database WHERE datname = %s", (dbname,))
            exists = cursor.fetchone()
    
            if not exists:
                try:
                    # Создание новой базы данных
                    with conn.cursor() as cursor:
                        cursor.execute(f"CREATE DATABASE {dbname}")
                        print(f"База данных '{dbname}' создана.")
                        self.create_user_table()
                except Exception as e:
                    print(f'Ошибка {e}')
                finally:
                    if conn:
                        conn.close()
            else:
                print(f"База данных '{dbname}' уже существует.")
    
        def create_user_table(self):
            try:
                with self.database as cursor:
                    cursor.execute(f'CREATE TABLE IF NOT EXISTS public.users '
                                   f"(id integer NOT NULL, user_id integer NOT NULL, PRIMARY KEY (id));"
                                   f'ALTER TABLE IF EXISTS public.users OWNER to postgres;')
                    print(f"[INFO] Таблица пользователей успешно создана")
            except Exception as e:
                print(f'Ошибка при создании новой таблицы: {e}')
    
        def exists(self):
            """Проверяем на наличие в базе данных"""
            try:
                with self.database as cursor:
                    cursor.execute("SELECT * FROM users")
                    print("[INFO] Данные успешно получены")
                    return cursor.fetchall()
            except errors.OperationalError:
                self.create_database_if_not_exists()
                return self.exists()
    
    
    db = Admin_connected()
    print(db.exists())
    Ответ написан
    Комментировать
  • Как запускать приложение на винрутальном android устройстве?

    @Wolfengo
    Я ещё зелёный, сильно не душите
    Нажми "open android...", у тебя откроется телефон, дождись загрузки, если это его первый запуск и нажимай Run
    Ответ написан
  • Как создать Телеграм-бот на python, который ищет из гугл таблицы всю информацию?

    @Wolfengo
    Я ещё зелёный, сильно не душите
    https://translated.turbopages.org/proxy_u/en-ru.ru...

    Вот тебе в помощь первая часть, по настройке гугл таблиц и питона, всё очень понятно расписано.
    Сделав это, ты уже разберёшься что делать дальше
    Ответ написан
    Комментировать
  • Как избежать повторения функции при получении коложа фотографий?

    @Wolfengo Автор вопроса
    Я ещё зелёный, сильно не душите
    Я нашёл решение этого вопроса. Я сделал так, чтобы через content_types=["text", "photo"]
    бот пересылал медиагруппу вместе с подписью (если не нужно, можно убрать), если 1 фото, то 1 фото с подписью и если текст, то перешлёт текст.

    Долее код подбивайте под ваши нужды

    import asyncio
    from typing import List, Union
    
    from aiogram import Bot, Dispatcher, executor, types
    from aiogram.dispatcher.handler import CancelHandler
    from aiogram.dispatcher.middlewares import BaseMiddleware
    
    bot = Bot(token="")
    dp = Dispatcher(bot)
    
    
    class AlbumMiddleware(BaseMiddleware):
    
        album_data: dict = {}
    
        def __init__(self, latency: Union[int, float] = 0.01):
            self.latency = latency
            super().__init__()
    
        async def on_process_message(self, message: types.Message, data: dict):
            if not message.media_group_id:
                self.album_data[message.from_user.id] = [message]
    
                message.conf["is_last"] = True
                data["album"] = self.album_data[message.from_user.id]
                await asyncio.sleep(self.latency)
            else:
                try:
                    self.album_data[message.media_group_id].append(message)
                    raise CancelHandler()
                except KeyError:
                    self.album_data[message.media_group_id] = [message]
                    await asyncio.sleep(self.latency)
    
                    message.conf["is_last"] = True
                    data["album"] = self.album_data[message.media_group_id]
    
        async def on_post_process_message(self, message: types.Message):
            if not message.media_group_id:
                if message.from_user.id and message.conf.get("is_last"):
                    del self.album_data[message.from_user.id]
            else:
                if message.media_group_id and message.conf.get("is_last"):
                    del self.album_data[message.media_group_id]
    
    
    @dp.message_handler(content_types=['text', 'photo'])
    async def handle_albums(message: types.Message, album: List[types.Message]):
        if not message.media_group_id:
            if message.photo:
                await bot.send_photo(chat_id=message.chat.id, photo=message.photo[-1].file_id, caption=message.caption)
            else:
                await bot.send_message(message.chat.id, message.text)
        else:
            media_group = types.MediaGroup()
            for obj in album:
                if obj.photo:
                    file_id = obj.photo[-1].file_id
                    caption = album[0].caption
                else:
                    file_id = obj[obj.content_type].file_id
    
                try:
                    media_group.attach({"media": file_id, "type": obj.content_type})
                    media_group.media[0]["caption"] = caption
                except ValueError:
                    return await message.answer("Этот тип не поддерживается aiogram.")
    
            await message.answer_media_group(media_group)
    
    
    if __name__ == "__main__":
        dp.middleware.setup(AlbumMiddleware())
        executor.start_polling(dp, skip_updates=True)
    Ответ написан
    Комментировать
  • Могу ли я параллельно изучать языки программирования?

    @Wolfengo
    Я ещё зелёный, сильно не душите
    Не гонись за всем зайцами сразу, так ни одного не поймаешь, всему своё время, успеешь ещё выучить другие языки
    Ответ написан
    1 комментарий
  • Ошибка при выполнение команды, как её исправить?

    @Wolfengo
    Я ещё зелёный, сильно не душите
    ты используешь 2 библиотеки для написания бота? telebot и telethon, это разные библиотеки и брать "типы" тебе нужно не из telethon, а из telebot
    Ответ написан
    Комментировать
  • Создать переменные из массива чтобы оно само создало?

    @Wolfengo
    Я ещё зелёный, сильно не душите
    В программировании нужно сначала гуглить, а потом задавать вопрос :)
    https://ru.stackoverflow.com/questions/900540/Можн...
    Ответ написан
    1 комментарий
  • Как заставить бота услышать другого бота в группе Telegram?

    @Wolfengo Автор вопроса
    Я ещё зелёный, сильно не душите
    Пересылаю ответ из комментов.

    Проблема не в библиотеке, проблема в API.
    Общаться с ботами можно с помощью клиентского API (смотреть в сторону библиотеки telethon).

    Если получится реализовать, то дам знать конкретно
    Ответ написан
    Комментировать
  • Telebot, как зная ID сделать ссылку на пользователя?

    @Wolfengo Автор вопроса
    Я ещё зелёный, сильно не душите
    Я нашёл решение через "mem = message.from_user.username", он возвращает имя юзера, если его нету, то None.
    Как я понял, сделать ссылку на контакт (t.me/...) человека не возможно, если у него нет имени юзера, так что это будет, наверное, единственным решением
    Я сделал:
    bot.send_message(***id_admin***,
    f'Покупатель сделал покупку!\n'
    f'Покупатель: @{mem}\n'
    f'Выбор: {last_take_buy[-1]}',
    )
    Ответ написан
    Комментировать