-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: getChart #41
feat: getChart #41
Changes from 9 commits
e845067
9bdd1e5
6440891
0bcab50
f24609a
fe5558d
58667a4
b76bcaf
3952941
3cc3073
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,4 +11,4 @@ concurrency: | |
|
||
jobs: | ||
build: | ||
uses: ./.github/workflows/build.yaml | ||
uses: ./.github/workflows/build-and-test.yaml |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,10 +8,12 @@ | |
*.rock | ||
*.nix | ||
|
||
/proto/*.rs | ||
venv/ | ||
build/ | ||
*.charm | ||
.tox/ | ||
.coverage | ||
__pycache__/ | ||
*.py[cod] | ||
server.pid |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
syntax = "proto3"; | ||
|
||
package ratings.features.common; | ||
|
||
message Rating { | ||
string snap_id = 1; | ||
uint64 total_votes = 2; | ||
RatingsBand ratings_band = 3; | ||
} | ||
|
||
enum RatingsBand { | ||
VERY_GOOD = 0; | ||
GOOD = 1; | ||
NEUTRAL = 2; | ||
POOR = 3; | ||
VERY_POOR = 4; | ||
INSUFFICIENT_VOTES = 5; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,16 +1,11 @@ | ||
use crate::app::AppContext; | ||
|
||
use self::protobuf::{App, GetRatingRequest, GetRatingResponse}; | ||
pub use protobuf::app_server; | ||
use crate::features::pb::app::{GetRatingRequest, GetRatingResponse}; | ||
use tonic::{Request, Response, Status}; | ||
|
||
use super::{service::AppService, use_cases}; | ||
|
||
pub mod protobuf { | ||
pub use self::app_server::App; | ||
use crate::features::pb::app::app_server::App; | ||
|
||
tonic::include_proto!("ratings.features.app"); | ||
} | ||
use super::{service::AppService, use_cases}; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason to not There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. No reason, totally agree with |
||
|
||
#[tonic::async_trait] | ||
impl App for AppService { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
pub mod entities; | ||
mod errors; | ||
mod infrastructure; | ||
pub mod interface; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
use crate::app::AppContext; | ||
use crate::{app::AppContext, features::common::entities::Rating}; | ||
use tracing::error; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe merge with the |
||
|
||
use super::{entities::Rating, errors::AppError, infrastructure::get_votes_by_snap_id}; | ||
use super::{errors::AppError, infrastructure::get_votes_by_snap_id}; | ||
|
||
pub async fn get_rating(app_ctx: &AppContext, snap_id: String) -> Result<Rating, AppError> { | ||
let votes = get_votes_by_snap_id(app_ctx, &snap_id) | ||
|
@@ -11,7 +11,7 @@ pub async fn get_rating(app_ctx: &AppContext, snap_id: String) -> Result<Rating, | |
AppError::Unknown | ||
})?; | ||
|
||
let rating = Rating::new(snap_id, votes); | ||
let rating = Rating::new(votes); | ||
|
||
Ok(rating) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
use sqlx::FromRow; | ||
|
||
use crate::features::common::entities::{calculate_band, Rating, VoteSummary}; | ||
use crate::features::pb::chart as pb; | ||
|
||
pub struct Chart { | ||
pub timeframe: pb::Timeframe, | ||
pub chart_data: Vec<ChartData>, | ||
} | ||
|
||
impl Chart { | ||
pub fn new(timeframe: pb::Timeframe, data: Vec<VoteSummary>) -> Self { | ||
let mut chart_data: Vec<ChartData> = | ||
data.into_iter().map(ChartData::from_vote_summary).collect(); | ||
|
||
chart_data.sort_by(|a, b| { | ||
b.raw_rating | ||
.partial_cmp(&a.raw_rating) | ||
.unwrap_or(std::cmp::Ordering::Equal) | ||
}); | ||
|
||
// Take only the first 20 elements from the sorted chart_data | ||
let top_20: Vec<ChartData> = chart_data.into_iter().take(20).collect(); | ||
|
||
Chart { | ||
timeframe, | ||
chart_data: top_20, | ||
} | ||
} | ||
} | ||
|
||
#[derive(Debug, Clone, FromRow)] | ||
pub struct ChartData { | ||
pub raw_rating: f32, | ||
pub rating: Rating, | ||
} | ||
|
||
impl ChartData { | ||
pub fn from_vote_summary(vote_summary: VoteSummary) -> 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, | ||
}; | ||
let raw_rating = raw_rating.unwrap_or(0.0) as f32; | ||
Self { raw_rating, rating } | ||
} | ||
|
||
pub fn into_dto(self) -> pb::ChartData { | ||
pb::ChartData { | ||
raw_rating: self.raw_rating, | ||
rating: Some(self.rating.into_dto()), | ||
} | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
use thiserror::Error; | ||
|
||
#[derive(Error, Debug)] | ||
pub enum ChartError { | ||
#[error("failed to get chart for timeframe")] | ||
FailedToGetChart, | ||
#[error("unknown chart error")] | ||
Unknown, | ||
#[error("could not find data for given timeframe")] | ||
NotFound, | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This also applies to Line 1 and later lines, but probably best to merge all the
use crate::{...}
into a single line so it's easier to find all imports.