From b7de851580e58364cf85f2359d7af4333f632b0c Mon Sep 17 00:00:00 2001 From: Vlad Date: Sun, 25 May 2025 11:29:08 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9E=D0=B1=D0=BD=D0=BE=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D1=8B=20=D0=BE=D0=B1=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D1=87?= =?UTF-8?q?=D0=B8=D0=BA=D0=B8=20=D0=B2=20main.py=20=D0=B4=D0=BB=D1=8F=20?= =?UTF-8?q?=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=B3=D0=BB=D0=BE=D0=B1=D0=B0=D0=BB=D1=8C?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BE=D0=B1=D1=8A=D0=B5=D0=BA=D1=82?= =?UTF-8?q?=D0=B0=20oracle=5Fdb=20=D0=B2=D0=BC=D0=B5=D1=81=D1=82=D0=BE=20?= =?UTF-8?q?=D0=BF=D0=B5=D1=80=D0=B5=D0=B4=D0=B0=D0=B2=D0=B0=D0=B5=D0=BC?= =?UTF-8?q?=D0=BE=D0=B3=D0=BE=20db.=20=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD?= =?UTF-8?q?=20=D0=BD=D0=B5=D0=B8=D1=81=D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D1=83?= =?UTF-8?q?=D0=B5=D0=BC=D1=8B=D0=B9=20=D1=84=D0=B0=D0=B9=D0=BB=20=D1=88?= =?UTF-8?q?=D0=B0=D0=B1=D0=BB=D0=BE=D0=BD=D0=B0=20telegram=5Fpost=5Ftempla?= =?UTF-8?q?te=5Fdecodevin.j2.=20=D0=AD=D1=82=D0=BE=20=D1=83=D0=BB=D1=83?= =?UTF-8?q?=D1=87=D1=88=D0=B0=D0=B5=D1=82=20=D1=87=D0=B8=D1=82=D0=B0=D0=B5?= =?UTF-8?q?=D0=BC=D0=BE=D1=81=D1=82=D1=8C=20=D0=BA=D0=BE=D0=B4=D0=B0=20?= =?UTF-8?q?=D0=B8=20=D1=83=D0=BF=D1=80=D0=BE=D1=89=D0=B0=D0=B5=D1=82=20?= =?UTF-8?q?=D1=83=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D0=B5=D0=BC=20=D0=BA=20=D0=B1=D0=B0=D0=B7=D0=B5=20=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD=D0=BD=D1=8B=D1=85.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .cursor/rules/termital.mdc | 6 +++ main.py | 69 ++++++++++++++++++++--------- telegram_post_template_decodevin.j2 | 34 -------------- 3 files changed, 55 insertions(+), 54 deletions(-) create mode 100644 .cursor/rules/termital.mdc delete mode 100644 telegram_post_template_decodevin.j2 diff --git a/.cursor/rules/termital.mdc b/.cursor/rules/termital.mdc new file mode 100644 index 0000000..4ca3d50 --- /dev/null +++ b/.cursor/rules/termital.mdc @@ -0,0 +1,6 @@ +--- +description: +globs: +alwaysApply: false +--- +Разаабаотка ведется в ОС Windows 10, все консольные команды формируй с учетом этого \ No newline at end of file diff --git a/main.py b/main.py index f18bd65..9e831d9 100644 --- a/main.py +++ b/main.py @@ -21,7 +21,7 @@ else: TOKEN = getenv("BOT_TOKEN") BOTNAME = getenv("BOT_NAME") -# SALVAGEDB_TOKEN=getenv("SALVAGEDB_TOKEN",'1234567890') + oracle_db = OracleDatabase( user= getenv("db_user"), @@ -38,9 +38,12 @@ class VinStates(StatesGroup): # Command handler @dp.message(Command("start")) -async def command_start_handler(message: Message, db: OracleDatabase) -> None: +async def command_start_handler(message: Message, db: OracleDatabase = None) -> None: + # Используем переданный db или глобальный oracle_db + database = db or oracle_db + # Сохраняем данные пользователя при каждом взаимодействии - await db.save_user(message.from_user, "start_command") + await database.save_user(message.from_user, "start_command") welcome_text = ( "Welcome to SalvagedbBot — your trusted assistant for vehicle history checks via VIN!\n\n" @@ -64,9 +67,12 @@ async def command_start_handler(message: Message, db: OracleDatabase) -> None: @dp.callback_query(lambda c: c.data == "decode_vin") -async def decode_vin_callback(callback: CallbackQuery, state: FSMContext, db: OracleDatabase): +async def decode_vin_callback(callback: CallbackQuery, state: FSMContext, db: OracleDatabase = None): + # Используем переданный db или глобальный oracle_db + database = db or oracle_db + # Сохраняем данные пользователя при нажатии кнопки - await db.save_user(callback.from_user, "decode_vin_button") + await database.save_user(callback.from_user, "decode_vin_button") await callback.message.answer("Please enter the vehicle VIN.") await state.set_state(VinStates.waiting_for_vin) @@ -74,19 +80,25 @@ async def decode_vin_callback(callback: CallbackQuery, state: FSMContext, db: Or @dp.callback_query(lambda c: c.data == "main_menu") -async def main_menu_callback(callback: CallbackQuery, state: FSMContext, db: OracleDatabase): +async def main_menu_callback(callback: CallbackQuery, state: FSMContext, db: OracleDatabase = None): + # Используем переданный db или глобальный oracle_db + database = db or oracle_db + # Сохраняем данные пользователя при возврате в главное меню - await db.save_user(callback.from_user, "main_menu_button") + await database.save_user(callback.from_user, "main_menu_button") await state.clear() - await command_start_handler(callback.message, db) + await command_start_handler(callback.message, database) await callback.answer() @dp.callback_query(lambda c: c.data and c.data.startswith("pay_detailed_info:")) -async def pay_detailed_info_callback(callback: CallbackQuery, db: OracleDatabase): +async def pay_detailed_info_callback(callback: CallbackQuery, db: OracleDatabase = None): + # Используем переданный db или глобальный oracle_db + database = db or oracle_db + # Сохраняем данные пользователя при инициации платежа - await db.save_user(callback.from_user, "payment_initiation") + await database.save_user(callback.from_user, "payment_initiation") # Extract VIN from callback data vin = callback.data.split(":")[1] @@ -105,14 +117,17 @@ async def pay_detailed_info_callback(callback: CallbackQuery, db: OracleDatabase @dp.message(VinStates.waiting_for_vin) -async def process_vin(message: Message, state: FSMContext, db: OracleDatabase): +async def process_vin(message: Message, state: FSMContext, db: OracleDatabase = None): + # Используем переданный db или глобальный oracle_db + database = db or oracle_db + # Сохраняем данные пользователя при обработке VIN - await db.save_user(message.from_user, "vin_processing") + await database.save_user(message.from_user, "vin_processing") vin = message.text.strip().upper() if len(vin) == 17 and vin.isalnum() and all(c not in vin for c in ["I", "O", "Q"]): try: - make, model, year, cnt = await db.fetch_vin_info(vin) + make, model, year, cnt = await database.fetch_vin_info(vin) logging.info(f"Decode VIN 1st step: make: {make}, model: {model}, year: {year}, cnt: {cnt}") response_text = f"🚗 **{year} {make} {model}**\n\n" if cnt == 0: @@ -140,14 +155,22 @@ async def process_vin(message: Message, state: FSMContext, db: OracleDatabase): @dp.pre_checkout_query() -async def pre_checkout_handler(pre_checkout_query: PreCheckoutQuery): +async def pre_checkout_handler(pre_checkout_query: PreCheckoutQuery, db: OracleDatabase = None): + # Используем переданный db или глобальный oracle_db + database = db or oracle_db + + # Сохраняем данные пользователя при pre-checkout + await database.save_user(pre_checkout_query.from_user, "pre_checkout") await pre_checkout_query.answer(ok=True) ADMIN_USER_ID = int(getenv("ADMIN_USER_ID", "0")) # ID администратора из переменных окружения @dp.message(Command("admin_stats")) -async def admin_stats_handler(message: Message, db: OracleDatabase): +async def admin_stats_handler(message: Message, db: OracleDatabase = None): + # Используем переданный db или глобальный oracle_db + database = db or oracle_db + # Проверяем, является ли пользователь администратором if message.from_user.id != ADMIN_USER_ID: await message.answer("❌ Access denied. This command is for administrators only.") @@ -155,7 +178,7 @@ async def admin_stats_handler(message: Message, db: OracleDatabase): try: # Получаем общую статистику - stats = await db.get_users_summary() + stats = await database.get_users_summary() # Формируем отчет report = f""" @@ -184,10 +207,13 @@ async def admin_stats_handler(message: Message, db: OracleDatabase): @dp.message(lambda message: message.successful_payment) -async def successful_payment_handler(message: Message, db: OracleDatabase): +async def successful_payment_handler(message: Message, db: OracleDatabase = None): + # Используем переданный db или глобальный oracle_db + database = db or oracle_db + # Сохраняем данные о платеже пользователя - await db.save_user(message.from_user, "successful_payment") - await db.update_user_payment(message.from_user.id, 1.0) # 1 Telegram Star + await database.save_user(message.from_user, "successful_payment") + await database.update_user_payment(message.from_user.id, 1.0) # 1 Telegram Star payload = message.successful_payment.invoice_payload @@ -196,7 +222,7 @@ async def successful_payment_handler(message: Message, db: OracleDatabase): try: # Get detailed information from database - detailed_info = await db.fetch_detailed_vin_info(vin) + detailed_info = await database.fetch_detailed_vin_info(vin) if detailed_info and detailed_info['all_params']: params = detailed_info['all_params'] @@ -357,7 +383,10 @@ async def successful_payment_handler(message: Message, db: OracleDatabase): async def on_startup(): await oracle_db.connect() + # Регистрируем middleware для всех типов событий dp.message.middleware(DbSessionMiddleware(oracle_db)) + dp.callback_query.middleware(DbSessionMiddleware(oracle_db)) + dp.pre_checkout_query.middleware(DbSessionMiddleware(oracle_db)) async def on_shutdown(): diff --git a/telegram_post_template_decodevin.j2 b/telegram_post_template_decodevin.j2 deleted file mode 100644 index 9d2c9d6..0000000 --- a/telegram_post_template_decodevin.j2 +++ /dev/null @@ -1,34 +0,0 @@ -🚗 **{{ year }} {{ make }} {{ model }}** -{{ trim if trim else '' }} - -📋 **BASIC INFO** -• **Make:** {{ make }} -• **Model:** {{ model }} -• **Year:** {{ model_year }} -• **Type:** {{ vehicle_type }} -• **Body:** {{ body_class }} -{% if doors %}• **Doors:** {{ doors }}{% endif %} - -🔧 **ENGINE** -{% if engine_cylinders %}• **Engine:** {{ displacement_l }}L V{{ engine_cylinders }}{% endif %} -{% if displacement_l %}• **Displacement:** {{ displacement_l }}L ({{ displacement_ci }} CI){% endif %} -{% if engine_configuration %}• **Config:** {{ engine_configuration }}{% endif %} -{% if engine_brake_hp %}• **Power:** {{ engine_brake_hp }} HP{% if engine_brake_hp_range %} (up to {{ engine_brake_hp_range }} HP){% endif %}{% endif %} -{% if engine_power_kw %}• **Power (kW):** {{ engine_power_kw }} kW{% endif %} -{% if fuel_type_primary %}• **Fuel:** {{ fuel_type_primary }}{% endif %} -{% if valve_train_design %}• **Valve Train:** {{ valve_train_design }}{% endif %} -{% if engine_manufacturer %}• **Engine Mfg:** {{ engine_manufacturer }}{% endif %} - -{% if seat_belts_type %}🛡️ **SAFETY** -• **Seat Belts:** {{ seat_belts_type }} -{% endif %} - -🏭 **MANUFACTURING** -{% if manufacturer_name %}• **Manufacturer:** {{ manufacturer_name }}{% endif %} -{% if plant_city and plant_state %}• **Made in:** {{ plant_city }}, {{ plant_state }}{% endif %} -{% if plant_country %}• **Country:** {{ plant_country }}{% endif %} - -{% if error_code and error_code == "0" %}✅ **No errors found**{% endif %} - ---- -📊 **Quick Specs:** {{ displacement_l }}L V{{ engine_cylinders if engine_cylinders else 'X' }} • {{ engine_brake_hp if engine_brake_hp else 'N/A' }} HP • {{ fuel_type_primary if fuel_type_primary else 'N/A' }} • {{ doors if doors else 'N/A' }}-door \ No newline at end of file