diff --git a/app.py b/app.py index f207c90..79d1fa2 100644 --- a/app.py +++ b/app.py @@ -1952,30 +1952,38 @@ def suggest_products(): @app.route("/all_products") def all_products(): sort = request.args.get("sort", "popularity") - limit = request.args.get("limit", type=int) or 50 + limit = request.args.get("limit", type=int) or 100 offset = request.args.get("offset", type=int) or 0 - rows = db.session.query(Item.name, Item.list_id).distinct().all() + ItemAlias = aliased(Item) + SuggestedAlias = aliased(SuggestedProduct) - usage_map = defaultdict(set) - original_names = {} + base_query = db.session.query( + func.lower(func.trim(ItemAlias.name)).label("normalized_name"), + func.count(func.distinct(ItemAlias.list_id)).label("count"), + func.min(ItemAlias.name).label("original_name") + ).join( + SuggestedAlias, + func.lower(func.trim(ItemAlias.name)) == func.lower(func.trim(SuggestedAlias.name)) + ).group_by("normalized_name") - for raw_name, list_id in rows: - norm = normalize_name(raw_name) - usage_map[norm].add(list_id) - if norm not in original_names or len(raw_name) < len(original_names[norm]): - original_names[norm] = raw_name.strip() + if sort == "popularity": + base_query = base_query.order_by(func.count(func.distinct(ItemAlias.list_id)).desc(), "normalized_name") + else: + base_query = base_query.order_by("normalized_name") - counts = {k: len(v) for k, v in usage_map.items()} - sorted_keys = sorted( - counts.keys(), - key=lambda k: (-counts[k], k) if sort == "popularity" else k - ) + results = base_query.offset(offset).limit(limit).all() - paged_keys = sorted_keys[offset:offset + limit] - products = [{"name": original_names[k], "count": counts[k]} for k in paged_keys] + total_count = db.session.query(func.count()).select_from( + base_query.subquery() + ).scalar() - return jsonify({"products": products, "total_count": len(counts)}) + products = [{"name": row.original_name, "count": row.count} for row in results] + + return jsonify({ + "products": products, + "total_count": total_count + }) @app.route("/upload_receipt/", methods=["POST"])