From e169ad65a0938e8bd844ef95c5681f0a60121e5c Mon Sep 17 00:00:00 2001 From: Vlad Date: Sun, 18 May 2025 19:11:56 +0300 Subject: [PATCH] =?UTF-8?q?=D0=98=D0=B7=D0=BC=D0=B5=D0=BD=D0=B5=D0=BD=20?= =?UTF-8?q?=D1=81=D0=BF=D0=BE=D1=81=D0=BE=D0=B1=20=D0=BF=D0=BE=D0=BB=D1=83?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D0=B7=D0=BD=D0=B0=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20capcha=5Fscore=20=D0=B8=D0=B7=20=D0=BF?= =?UTF-8?q?=D0=B5=D1=80=D0=B5=D0=BC=D0=B5=D0=BD=D0=BD=D0=BE=D0=B9=20=D0=BE?= =?UTF-8?q?=D0=BA=D1=80=D1=83=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F.=20=D0=98?= =?UTF-8?q?=D1=81=D0=BF=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=20=D0=BF=D0=BE?= =?UTF-8?q?=D1=80=D1=8F=D0=B4=D0=BE=D0=BA=20=D1=81=D0=BE=D1=80=D1=82=D0=B8?= =?UTF-8?q?=D1=80=D0=BE=D0=B2=D0=BA=D0=B8=20=D1=80=D0=B5=D0=B7=D1=83=D0=BB?= =?UTF-8?q?=D1=8C=D1=82=D0=B0=D1=82=D0=BE=D0=B2=20=D0=B7=D0=B0=D0=BF=D1=80?= =?UTF-8?q?=D0=BE=D1=81=D0=B0=20=D0=B2=20=D0=B1=D0=B0=D0=B7=D0=B5=20=D0=B4?= =?UTF-8?q?=D0=B0=D0=BD=D0=BD=D1=8B=D1=85=20=D0=BD=D0=B0=20=D1=83=D0=B1?= =?UTF-8?q?=D1=8B=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5.=20=D0=98=D1=81=D0=BF?= =?UTF-8?q?=D1=80=D0=B0=D0=B2=D0=BB=D0=B5=D0=BD=D1=8B=20=D0=BE=D1=82=D1=81?= =?UTF-8?q?=D1=82=D1=83=D0=BF=D1=8B=20=D0=B8=20=D1=84=D0=BE=D1=80=D0=BC?= =?UTF-8?q?=D0=B0=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0=D0=BD=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BA=D0=BE=D0=B4=D0=B0=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=BE?= =?UTF-8?q?=D0=BE=D1=82=D0=B2=D0=B5=D1=82=D1=81=D1=82=D0=B2=D0=B8=D1=8F=20?= =?UTF-8?q?=D1=81=D1=82=D0=B0=D0=BD=D0=B4=D0=B0=D1=80=D1=82=D0=B0=D0=BC.?= =?UTF-8?q?=20=D0=A3=D0=B4=D0=B0=D0=BB=D0=B5=D0=BD=20=D0=BD=D0=B5=D0=BD?= =?UTF-8?q?=D1=83=D0=B6=D0=BD=D1=8B=D0=B9=20=D1=84=D0=B0=D0=B9=D0=BB=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B0=D0=B2=D0=B8=D0=BB=20=D0=B4=D0=BB=D1=8F=20Pyt?= =?UTF-8?q?hon/Flask.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../python-flask.mdc => .clinerules/rules.md | 5 - app.py | 14 +-- rules.md | 93 +++++++++++++++++++ telegram_bot.py | 40 ++++++++ 4 files changed, 140 insertions(+), 12 deletions(-) rename .cursor/rules/python-flask.mdc => .clinerules/rules.md (98%) create mode 100644 rules.md create mode 100644 telegram_bot.py diff --git a/.cursor/rules/python-flask.mdc b/.clinerules/rules.md similarity index 98% rename from .cursor/rules/python-flask.mdc rename to .clinerules/rules.md index c5043a2..3281103 100644 --- a/.cursor/rules/python-flask.mdc +++ b/.clinerules/rules.md @@ -1,8 +1,3 @@ ---- -description: -globs: -alwaysApply: true ---- You are an expert in Python, Flask, and scalable API development. diff --git a/app.py b/app.py index 03125c8..5aba11b 100644 --- a/app.py +++ b/app.py @@ -28,7 +28,7 @@ import logging -capcha_score: float = 0.1 +capcha_score: float = os.environ.get('CAPCHA_SCORE',0.5) capcha_site = '6LcJpHMgAAAAAMQLNY_g8J2Kv_qmCGureRN_lbGl' capcha_site_sec = '6LcJpHMgAAAAAIUf4Jg_7NvawQKZoLoVypDU6-d8' capcha_site_url='https://www.google.com/recaptcha/api/siteverify' @@ -583,7 +583,7 @@ def restfact_detail(): if app.debug: logger.debug(json.dumps(ret)) return response - cur.execute("select vin, ip, status, dt, cost from billing where access_code = :p1 and dt > CAST(SYSTIMESTAMP AT TIME ZONE 'UTC' AS DATE) - 45 and made = 1 order by id", {'p1': str(access_code)}) + cur.execute("select vin, ip, status, dt, cost from billing where access_code = :p1 and dt > CAST(SYSTIMESTAMP AT TIME ZONE 'UTC' AS DATE) - 45 and made = 1 order by id desc", {'p1': str(access_code)}) res = cur.fetchall() if len(res) <= 0: ret = {'status': 'billing not found'} @@ -704,17 +704,17 @@ def api_search_v2(): 'cost': found_price, 'records': dat } - response = app.response_class( + response = app.response_class( response=json.dumps(ret), status=200, mimetype='application/json' ) - if app.debug: + if app.debug: logger.debug(json.dumps(ret)) - cur.execute("insert into billing(access_code, vin, ip, status, dt, cost) values (:p1, :p2, :p3, :p4, CAST(SYSTIMESTAMP AT TIME ZONE 'UTC' AS DATE), :p5)", + cur.execute("insert into billing(access_code, vin, ip, status, dt, cost) values (:p1, :p2, :p3, :p4, CAST(SYSTIMESTAMP AT TIME ZONE 'UTC' AS DATE), :p5)", {'p1': str(access_code), 'p2': str(vin), 'p3': str(user_ip), 'p4': 'FOUND', 'p5': found_price}) - conn.commit() - return response + conn.commit() + return response else: # nor found diff --git a/rules.md b/rules.md new file mode 100644 index 0000000..3281103 --- /dev/null +++ b/rules.md @@ -0,0 +1,93 @@ + + You are an expert in Python, Flask, and scalable API development. + + Key Principles + - Write concise, technical responses with accurate Python examples. + - Use functional, declarative programming; avoid classes where possible except for Flask views. + - Prefer iteration and modularization over code duplication. + - Use descriptive variable names with auxiliary verbs (e.g., is_active, has_permission). + - Use lowercase with underscores for directories and files (e.g., blueprints/user_routes.py). + - Favor named exports for routes and utility functions. + - Use the Receive an Object, Return an Object (RORO) pattern where applicable. + + Python/Flask + - Use def for function definitions. + - Use type hints for all function signatures where possible. + - File structure: Flask app initialization, blueprints, models, utilities, config. + - Avoid unnecessary curly braces in conditional statements. + - For single-line statements in conditionals, omit curly braces. + - Use concise, one-line syntax for simple conditional statements (e.g., if condition: do_something()). + + Error Handling and Validation + - Prioritize error handling and edge cases: + - Handle errors and edge cases at the beginning of functions. + - Use early returns for error conditions to avoid deeply nested if statements. + - Place the happy path last in the function for improved readability. + - Avoid unnecessary else statements; use the if-return pattern instead. + - Use guard clauses to handle preconditions and invalid states early. + - Implement proper error logging and user-friendly error messages. + - Use custom error types or error factories for consistent error handling. + + Dependencies + - Flask + - Flask-RESTful (for RESTful API development) + - Flask-SQLAlchemy (for ORM) + - Flask-Migrate (for database migrations) + - Marshmallow (for serialization/deserialization) + - Flask-JWT-Extended (for JWT authentication) + + Flask-Specific Guidelines + - Use Flask application factories for better modularity and testing. + - Organize routes using Flask Blueprints for better code organization. + - Use Flask-RESTful for building RESTful APIs with class-based views. + - Implement custom error handlers for different types of exceptions. + - Use Flask's before_request, after_request, and teardown_request decorators for request lifecycle management. + - Utilize Flask extensions for common functionalities (e.g., Flask-SQLAlchemy, Flask-Migrate). + - Use Flask's config object for managing different configurations (development, testing, production). + - Implement proper logging using Flask's app.logger. + - Use Flask-JWT-Extended for handling authentication and authorization. + + Performance Optimization + - Use Flask-Caching for caching frequently accessed data. + - Implement database query optimization techniques (e.g., eager loading, indexing). + - Use connection pooling for database connections. + - Implement proper database session management. + - Use background tasks for time-consuming operations (e.g., Celery with Flask). + + Key Conventions + 1. Use Flask's application context and request context appropriately. + 2. Prioritize API performance metrics (response time, latency, throughput). + 3. Structure the application: + - Use blueprints for modularizing the application. + - Implement a clear separation of concerns (routes, business logic, data access). + - Use environment variables for configuration management. + + Database Interaction + - Use Flask-SQLAlchemy for ORM operations. + - Implement database migrations using Flask-Migrate. + - Use SQLAlchemy's session management properly, ensuring sessions are closed after use. + + Serialization and Validation + - Use Marshmallow for object serialization/deserialization and input validation. + - Create schema classes for each model to handle serialization consistently. + + Authentication and Authorization + - Implement JWT-based authentication using Flask-JWT-Extended. + - Use decorators for protecting routes that require authentication. + + Testing + - Write unit tests using pytest. + - Use Flask's test client for integration testing. + - Implement test fixtures for database and application setup. + + API Documentation + - Use Flask-RESTX or Flasgger for Swagger/OpenAPI documentation. + - Ensure all endpoints are properly documented with request/response schemas. + + Deployment + - Use Gunicorn or uWSGI as WSGI HTTP Server. + - Implement proper logging and monitoring in production. + - Use environment variables for sensitive information and configuration. + + Refer to Flask documentation for detailed information on Views, Blueprints, and Extensions for best practices. + \ No newline at end of file diff --git a/telegram_bot.py b/telegram_bot.py new file mode 100644 index 0000000..4194269 --- /dev/null +++ b/telegram_bot.py @@ -0,0 +1,40 @@ +import os +import requests +from flask import Flask +from telegram import Update, Bot +from telegram.ext import CommandHandler, CallbackContext, ApplicationBuilder + +app = Flask(__name__) +TOKEN = 'YOUR_TELEGRAM_BOT_TOKEN' # Замените на ваш токен + +async def start(update: Update, context: CallbackContext) -> None: + await update.message.reply_text('Привет! Используйте /decode для декодирования VIN или /check для проверки VIN.') + +def decode_vin(update: Update, context: CallbackContext) -> None: + vin = context.args[0] if context.args else None + if vin: + response = requests.get(f'http://localhost:5000/search?vin={vin}') + update.message.reply_text(response.text) + else: + update.message.reply_text('Пожалуйста, укажите VIN.') + +def check_vin(update: Update, context: CallbackContext) -> None: + vin = context.args[0] if context.args else None + if vin: + response = requests.get(f'http://localhost:5000/detail/{vin}.html') + update.message.reply_text(response.text) + else: + update.message.reply_text('Пожалуйста, укажите VIN.') + +def main() -> None: + application = ApplicationBuilder().token(TOKEN).build() + dispatcher = application.dispatcher + + dispatcher.add_handler(CommandHandler("start", start)) + dispatcher.add_handler(CommandHandler("decode", decode_vin)) + dispatcher.add_handler(CommandHandler("check", check_vin)) + + application.run_polling() + +if __name__ == '__main__': + main()