From 3856572447e3b3a8fb1bead16ab8327e04c3d8a2 Mon Sep 17 00:00:00 2001 From: Dennis Loose Date: Wed, 11 Dec 2024 17:09:19 +0100 Subject: [PATCH] feat: return snap_name in chart data --- Cargo.toml | 1 + proto/ratings_features_common.proto | 1 + src/grpc/app.rs | 2 ++ src/grpc/charts.rs | 4 +++- src/proto/ratings.features.common.rs | 2 ++ src/ratings/charts.rs | 36 ++++++++++++++++++++++------ src/ratings/rating.rs | 3 +++ 7 files changed, 41 insertions(+), 8 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 13803def..6896ab14 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,6 +18,7 @@ skip_cache = [] cached = { version = "0.54.0", features = ["async"] } dotenvy = "0.15" envy = "0.4" +futures = "0.3" http = "1.1.0" jsonwebtoken = "9.2" prost = "0.13.3" diff --git a/proto/ratings_features_common.proto b/proto/ratings_features_common.proto index 84a53d5e..de62d520 100644 --- a/proto/ratings_features_common.proto +++ b/proto/ratings_features_common.proto @@ -6,6 +6,7 @@ message Rating { string snap_id = 1; uint64 total_votes = 2; RatingsBand ratings_band = 3; + string snap_name = 4; } enum RatingsBand { diff --git a/src/grpc/app.rs b/src/grpc/app.rs index 88c7093c..bc9ed3c5 100644 --- a/src/grpc/app.rs +++ b/src/grpc/app.rs @@ -40,6 +40,7 @@ impl App for RatingService { snap_id, total_votes, ratings_band, + snap_name, } = Rating::from(votes); Ok(Response::new(GetRatingResponse { @@ -47,6 +48,7 @@ impl App for RatingService { snap_id, total_votes, ratings_band: ratings_band as i32, + snap_name, }), })) } diff --git a/src/grpc/charts.rs b/src/grpc/charts.rs index 4091f87f..4b9e9071 100644 --- a/src/grpc/charts.rs +++ b/src/grpc/charts.rs @@ -89,7 +89,7 @@ async fn get_chart_cached( ) -> Result> { let summaries = VoteSummary::get_for_timeframe(timeframe, category, conn!()).await?; - Ok(Chart::new(timeframe, summaries)) + Ok(Chart::new(timeframe, summaries, ctx).await?) } impl From for PbChartData { @@ -107,6 +107,7 @@ impl From for PbRating { snap_id: r.snap_id, total_votes: r.total_votes, ratings_band: r.ratings_band as i32, + snap_name: r.snap_name, } } } @@ -117,6 +118,7 @@ impl From for Rating { snap_id: r.snap_id, total_votes: r.total_votes, ratings_band: RatingsBand::from_repr(r.ratings_band).unwrap(), + snap_name: r.snap_name, } } } diff --git a/src/proto/ratings.features.common.rs b/src/proto/ratings.features.common.rs index 9e9f6a98..26c2d806 100644 --- a/src/proto/ratings.features.common.rs +++ b/src/proto/ratings.features.common.rs @@ -8,6 +8,8 @@ pub struct Rating { pub total_votes: u64, #[prost(enumeration = "RatingsBand", tag = "3")] pub ratings_band: i32, + #[prost(string, tag = "4")] + pub snap_name: ::prost::alloc::string::String, } #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] #[repr(i32)] diff --git a/src/ratings/charts.rs b/src/ratings/charts.rs index 5b6dfca9..9f17ffc1 100644 --- a/src/ratings/charts.rs +++ b/src/ratings/charts.rs @@ -1,7 +1,14 @@ //! Struct definitions for the charting feature for ratings. +use futures::future::try_join_all; + use crate::{ db::{Timeframe, VoteSummary}, - ratings::rating::{calculate_band, Rating}, + ratings::{ + get_snap_name, + rating::{calculate_band, Rating}, + Error, + }, + Context, }; use std::cmp::Ordering; @@ -12,8 +19,22 @@ pub struct Chart { } impl Chart { - pub fn new(timeframe: Timeframe, data: Vec) -> Self { - let mut data: Vec = data.into_iter().map(Into::into).collect(); + pub async fn new( + timeframe: Timeframe, + data: Vec, + ctx: &Context, + ) -> Result { + let mut data: Vec = try_join_all(data.into_iter().map(|vote_summary| async { + let snap_name = get_snap_name( + &vote_summary.snap_id, + &ctx.config.snapcraft_io_uri, + &ctx.http_client, + ) + .await?; + + Result::::Ok(ChartData::new(vote_summary, &snap_name)) + })) + .await?; data.sort_by(|a, b| { b.raw_rating @@ -22,10 +43,10 @@ impl Chart { }); // Take only the first 20 elements from the sorted chart_data - Chart { + Ok(Self { timeframe, data: data.into_iter().take(20).collect(), - } + }) } } @@ -35,13 +56,14 @@ pub struct ChartData { pub rating: Rating, } -impl From for ChartData { - fn from(vote_summary: VoteSummary) -> Self { +impl ChartData { + pub fn new(vote_summary: VoteSummary, snap_name: &str) -> Self { let (raw_rating, ratings_band) = calculate_band(&vote_summary); let rating = Rating { snap_id: vote_summary.snap_id, total_votes: vote_summary.total_votes as u64, ratings_band, + snap_name: snap_name.into(), }; let raw_rating = raw_rating.unwrap_or(0.0) as f32; diff --git a/src/ratings/rating.rs b/src/ratings/rating.rs index 7f62314f..8c8d6868 100644 --- a/src/ratings/rating.rs +++ b/src/ratings/rating.rs @@ -68,6 +68,8 @@ pub struct Rating { /// The descriptive indicator of "how good" this snap is based /// on aggregated ratings. pub ratings_band: RatingsBand, + /// The unique name of the snap. + pub snap_name: String, } impl From for Rating { @@ -78,6 +80,7 @@ impl From for Rating { snap_id: votes.snap_id, total_votes: votes.total_votes as u64, ratings_band, + snap_name: "".into(), } } }