116 lines
4.0 KiB
Python
116 lines
4.0 KiB
Python
from flask import jsonify, request
|
||
from db.handlers.product_handler import get_products_with_filters, get_product_by_id
|
||
from flask import Blueprint
|
||
import re
|
||
|
||
api_product = Blueprint('api_product', __name__, url_prefix='/products')
|
||
|
||
def clean_filter_value(value):
|
||
"""Очищает значение фильтра от мусора. Возвращает очищенное значение или None, если оно пустое."""
|
||
if value is None:
|
||
return None
|
||
if isinstance(value, str):
|
||
cleaned = value.strip().rstrip('/')
|
||
if not cleaned:
|
||
return None
|
||
return cleaned
|
||
return value
|
||
|
||
def parse_size(size_str):
|
||
"""
|
||
Парсит строку размера вида "110х2,2х500" и возвращает словарь с ключами diameter, wall_thickness, length.
|
||
"""
|
||
if not size_str:
|
||
return {}
|
||
# Заменяем запятую на точку для толщины
|
||
normalized = size_str.replace(',', '.')
|
||
match = re.match(r'(\d+)х([\d\.]+)х(\d+)', normalized)
|
||
if match:
|
||
return {
|
||
'diameter': int(match.group(1)),
|
||
'wall_thickness': float(match.group(2)),
|
||
'length': int(match.group(3))
|
||
}
|
||
return {}
|
||
|
||
@api_product.route('/', methods=['GET'], strict_slashes=False)
|
||
def get_products():
|
||
try:
|
||
category_id = request.args.get('categoryId', type=int)
|
||
if not category_id:
|
||
return jsonify({"error": "categoryId is required"}), 400
|
||
|
||
page = request.args.get('page', 1, type=int)
|
||
limit = request.args.get('limit', 9, type=int)
|
||
|
||
if page < 1:
|
||
page = 1
|
||
if limit < 1 or limit > 100:
|
||
limit = 9
|
||
|
||
filters = {}
|
||
excluded_params = {'categoryId', 'page', 'limit'}
|
||
|
||
# Обрабатываем все параметры запроса
|
||
for key, value in request.args.items():
|
||
if key in excluded_params:
|
||
continue
|
||
|
||
cleaned = clean_filter_value(value)
|
||
if cleaned is None:
|
||
continue
|
||
|
||
# Специальная обработка параметра size
|
||
if key == 'size':
|
||
size_parts = parse_size(cleaned)
|
||
for size_key, size_val in size_parts.items():
|
||
# Добавляем как одиночные фильтры (без списка)
|
||
filters[size_key] = size_val
|
||
else:
|
||
# Остальные фильтры (color, stiffness_class, и т.д.)
|
||
if ',' in cleaned:
|
||
parts = [p.strip() for p in cleaned.split(',') if p.strip()]
|
||
if parts:
|
||
filters[key] = parts
|
||
else:
|
||
filters[key] = cleaned
|
||
|
||
print("=== FINAL FILTERS ===", filters)
|
||
|
||
result = get_products_with_filters(
|
||
category_id=category_id,
|
||
page=page,
|
||
limit=limit,
|
||
filters=filters if filters else None
|
||
)
|
||
|
||
return jsonify(result), 200
|
||
|
||
except Exception as e:
|
||
return jsonify({"error": str(e)}), 500
|
||
|
||
|
||
@api_product.route('/<int:product_id>', methods=['GET'], strict_slashes=False)
|
||
def get_product(product_id):
|
||
try:
|
||
product = get_product_by_id(product_id)
|
||
if product:
|
||
return jsonify(product), 200
|
||
return jsonify({"error": "Product not found"}), 404
|
||
except Exception as e:
|
||
return jsonify({"error": str(e)}), 500
|
||
|
||
|
||
@api_product.route('/fetchById', methods=['GET'], strict_slashes=False)
|
||
def get_product_by_id_param():
|
||
try:
|
||
product_id = request.args.get('id', type=int)
|
||
if not product_id:
|
||
return jsonify({"error": "id parameter is required"}), 400
|
||
product = get_product_by_id(product_id)
|
||
if product:
|
||
return jsonify(product), 200
|
||
return jsonify({"error": "Product not found"}), 404
|
||
except Exception as e:
|
||
return jsonify({"error": str(e)}), 500
|