Customer Rating and review changes
This commit is contained in:
@@ -141,23 +141,50 @@ def product(product_id: int) -> dict:
|
||||
def _overall_rating(sources: List[dict]) -> Optional[dict]:
|
||||
"""The product's rating across the platforms that state one: the mean
|
||||
weighted by each platform's rating count (a platform that states no count
|
||||
weighs as 1). None when no platform states a rating - never a guess."""
|
||||
weighs as 1). None when no platform states a rating - never a guess.
|
||||
|
||||
One reading per platform: a site with a page per colour repeats the same
|
||||
model rating on each, and adding those up would multiply its count."""
|
||||
if not sources:
|
||||
return None
|
||||
weight = lambda s: max(int(s["review_count"] or 0), 1) # noqa: E731
|
||||
per_site: Dict[str, dict] = {}
|
||||
for s in sources:
|
||||
if s["site"] not in per_site or weight(s) > weight(per_site[s["site"]]):
|
||||
per_site[s["site"]] = s
|
||||
sources = list(per_site.values())
|
||||
total = sum(weight(s) for s in sources)
|
||||
value = sum(Decimal(s["rating"]) * weight(s) for s in sources) / total
|
||||
counts = [s["review_count"] for s in sources if s["review_count"]]
|
||||
return {
|
||||
"value": round(float(value), 1),
|
||||
"count": sum(counts) if counts else None,
|
||||
"breakdown": _breakdown(sources),
|
||||
"sources": [
|
||||
{"site": s["site"], "rating": float(s["rating"]), "review_count": s["review_count"], "source_url": s["source_url"]}
|
||||
{"site": s["site"], "rating": float(s["rating"]), "review_count": s["review_count"],
|
||||
"breakdown": s.get("rating_breakdown"), "source_url": s["source_url"]}
|
||||
for s in sources
|
||||
],
|
||||
}
|
||||
|
||||
|
||||
def _breakdown(sources: List[dict]) -> Optional[List[dict]]:
|
||||
"""5→1 star counts summed over the platforms that PUBLISH a breakdown.
|
||||
None when none does - never estimated from the few review texts held."""
|
||||
totals = {str(n): 0 for n in range(1, 6)}
|
||||
stated = False
|
||||
for s in sources:
|
||||
for star, n in (s.get("rating_breakdown") or {}).items():
|
||||
if star in totals and isinstance(n, int) and n > 0:
|
||||
totals[star] += n
|
||||
stated = True
|
||||
if not stated:
|
||||
return None
|
||||
total = sum(totals.values())
|
||||
return [{"stars": int(k), "count": totals[k], "percent": round(100 * totals[k] / total)}
|
||||
for k in ("5", "4", "3", "2", "1")]
|
||||
|
||||
|
||||
@router.get("/products/{product_id}/price-history")
|
||||
def price_history(product_id: int) -> List[dict]:
|
||||
with connect() as conn:
|
||||
|
||||
Reference in New Issue
Block a user