-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: use
format!
instead of +
putting string
- Loading branch information
Showing
8 changed files
with
177 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,121 @@ | ||
use crate::{ | ||
models::{activities::Activity, users::User}, | ||
routers::users::time::UserActivityTime, | ||
}; | ||
use bson::{doc, from_document}; | ||
use futures::stream::TryStreamExt; | ||
use mongodb::{Collection, Database}; | ||
use polars::{df, frame::DataFrame, prelude::NamedFrom, series::Series}; | ||
use std::sync::Arc; | ||
use tokio::sync::Mutex; | ||
|
||
async fn export(db: Arc<Mutex<Database>>) -> Result<DataFrame, String> { | ||
let db = db.lock().await; | ||
let mut df = df!( | ||
"_id" => &["".to_string()], | ||
"id" => &["0".to_string()], | ||
"name" => &["Example".to_string()], | ||
"class" => &["".to_string()], | ||
"on_campus" => &[0.0], | ||
"off_campus" => &[0.0], | ||
"social_practice" => &[0.0], | ||
"total" => &[0.0] | ||
) | ||
.unwrap(); | ||
|
||
let users_collection: Collection<User> = db.collection("users"); | ||
let activities_collection: Collection<Activity> = db.collection("activities"); | ||
|
||
let mut users = users_collection.find(doc! {}, None).await.unwrap(); | ||
|
||
while let Some(doc) = users.try_next().await.unwrap() { | ||
let pipeline = vec![ | ||
doc! { | ||
"$match": { | ||
"$or": [ | ||
{ "members._id": doc._id.clone() }, | ||
{ "members._id": doc._id.to_hex() } | ||
] | ||
} | ||
}, | ||
doc! { | ||
"$unwind": "$members" | ||
}, | ||
doc! { | ||
"$match": { | ||
"$or": [ | ||
{ "members._id": doc._id.clone() }, | ||
{ "members._id": doc._id.to_hex() } | ||
] | ||
} | ||
}, | ||
doc! { | ||
"$group": { | ||
"_id": "$members.mode", | ||
"totalDuration": { "$sum": "$members.duration" } | ||
} | ||
}, | ||
doc! { | ||
"$group": { | ||
"_id": null, | ||
"on_campus": { | ||
"$sum": { | ||
"$cond": [{ "$eq": ["$_id", "on-campus"] }, "$totalDuration", 0.0] | ||
} | ||
}, | ||
"off_campus": { | ||
"$sum": { | ||
"$cond": [{ "$eq": ["$_id", "off-campus"] }, "$totalDuration", 0.0] | ||
} | ||
}, | ||
"social_practice": { | ||
"$sum": { | ||
"$cond": [{ "$eq": ["$_id", "social-practice"] }, "$totalDuration", 0.0] | ||
} | ||
}, | ||
"total": { "$sum": "$totalDuration" } | ||
} | ||
}, | ||
doc! { | ||
"$project": { | ||
"_id": 0, | ||
"on_campus": 1, | ||
"off_campus": 1, | ||
"social_practice": 1, | ||
"total": 1 | ||
} | ||
}, | ||
]; | ||
let cursor = activities_collection.aggregate(pipeline, None).await; | ||
if let Err(_) = cursor { | ||
return Err("Failed to get cursor".to_string()); | ||
} | ||
let mut cursor = cursor.unwrap(); | ||
let result = cursor.try_next().await; | ||
if let Err(_) = result { | ||
return Err("Failed to get result".to_string()); | ||
} | ||
let result = result.unwrap(); | ||
if let None = result { | ||
return Err("Failed to get result".to_string()); | ||
} | ||
let result = result.unwrap(); | ||
let result: UserActivityTime = from_document(result).unwrap(); | ||
let extend = DataFrame::new(vec![ | ||
Series::new("_id", vec![doc._id.clone().to_hex()]), | ||
Series::new("id", vec![doc.id.clone()]), | ||
Series::new("name", vec![doc.name.clone()]), | ||
Series::new("class", vec!["".to_string()]), | ||
Series::new("on_campus", vec![result.on_campus]), | ||
Series::new("off_campus", vec![result.off_campus]), | ||
Series::new("social_practice", vec![result.social_practice]), | ||
Series::new("total", vec![result.total]), | ||
]); | ||
if let Err(_) = extend { | ||
return Err("Failed to create DataFrame".to_string()); | ||
} | ||
let extend = extend.unwrap(); | ||
df.extend(&extend).unwrap(); | ||
} | ||
Ok(df) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
use crate::{ | ||
models::{groups::GroupPermission, response::create_error}, | ||
utils::jwt::UserData, | ||
}; | ||
use axum::{ | ||
extract::Extension, | ||
http::StatusCode, | ||
response::{IntoResponse, Json}, | ||
}; | ||
use bson::doc; | ||
use mongodb::Database; | ||
use serde::{Deserialize, Serialize}; | ||
use std::sync::Arc; | ||
use tokio::sync::Mutex; | ||
|
||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)] | ||
#[serde(rename_all = "kebab-case")] | ||
pub enum ExportFormat { | ||
CSV, | ||
JSON, | ||
Excel, | ||
} | ||
|
||
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, Hash)] | ||
pub struct ExportActivityTimesOptions { | ||
pub start: u64, // Unix timestamp | ||
pub end: u64, // Unix timestamp | ||
pub format: ExportFormat, | ||
} | ||
|
||
pub async fn export_activity_times( | ||
Extension(db): Extension<Arc<Mutex<Database>>>, | ||
user: UserData, | ||
Json(options): Json<ExportActivityTimesOptions>, | ||
) -> impl IntoResponse { | ||
if !user.perms.contains(&GroupPermission::Admin) | ||
&& !user.perms.contains(&GroupPermission::Inspector) | ||
{ | ||
return create_error(StatusCode::FORBIDDEN, "Permission denied".to_string()); | ||
} | ||
|
||
(StatusCode::OK, Json("".to_string())) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
pub mod activities; | ||
pub mod auth; | ||
pub mod exports; | ||
pub mod users; |