Merge pull request #53 from EETagent/submission_progress

Submission progress
This commit is contained in:
Vojtěch Jungmann 2022-11-21 16:26:22 +01:00 committed by GitHub
commit e9ff241ea5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 118 additions and 7 deletions

View file

@ -59,6 +59,7 @@ async fn start() -> Result<(), rocket::Error> {
routes::candidate::submit_portfolio,
routes::candidate::is_portfolio_prepared,
routes::candidate::is_portfolio_submitted,
routes::candidate::submission_progress,
routes::candidate::download_portfolio,
],
)

View file

@ -3,7 +3,7 @@ use std::net::SocketAddr;
use portfolio_core::candidate_details::ApplicationDetails;
use portfolio_core::services::application_service::ApplicationService;
use portfolio_core::services::candidate_service::CandidateService;
use portfolio_core::services::portfolio_service::PortfolioService;
use portfolio_core::services::portfolio_service::{PortfolioService, SubmissionProgress};
use requests::LoginRequest;
use rocket::http::{Cookie, CookieJar, Status};
use rocket::response::status::Custom;
@ -128,6 +128,26 @@ pub async fn upload_cover_letter(
Ok("Letter added".to_string())
}
#[get("/submission_progress")]
pub async fn submission_progress(
conn: Connection<'_, Db>,
session: CandidateAuth
) -> Result<Json<SubmissionProgress>, Custom<String>> {
let candidate: entity::candidate::Model = session.into();
let progress = PortfolioService::get_submission_progress(candidate.application)
.await
.map_err(|e| {
Custom(
Status::from_code(e.code()).unwrap_or_default(),
e.to_string(),
)
})?;
Ok(
Json(progress)
)
}
// TODO: JSON
#[get["/is_cover_letter"]]
pub async fn is_cover_letter(session: CandidateAuth) -> Result<String, Custom<String>> {

View file

@ -1,20 +1,66 @@
use std::{path::{PathBuf, Path}};
use entity::candidate;
use sea_orm::DbConn;
use sea_orm::{DbConn};
use serde::{Serialize, ser::{SerializeStruct}};
use tokio::io::{AsyncReadExt, AsyncWriteExt};
use crate::{error::ServiceError, Query, crypto};
pub enum SubmissionProgress {
NoneInCache,
SomeInCache(Vec<FileType>),
AllInCache,
Submitted,
}
impl SubmissionProgress {
pub fn index(&self) -> usize {
match self {
SubmissionProgress::NoneInCache => 1,
SubmissionProgress::SomeInCache(_) => 2,
SubmissionProgress::AllInCache => 3,
SubmissionProgress::Submitted => 4,
}
}
}
// Serialize the enum so that the JSON contains status field and a list of files present in cache
impl Serialize for SubmissionProgress {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let mut progress = serializer.serialize_struct("SubmissionProgress", 2)?;
progress.serialize_field("status", &self.index())?;
match self {
SubmissionProgress::SomeInCache(files) => {
progress.serialize_field("files", files)?;
}
_ => {
progress.serialize_field("files", &Vec::<FileType>::new())?;
}
};
progress.end()
}
}
#[derive(Copy, Clone)]
enum FileType {
CoverLetterPdf,
PortfolioLetterPdf,
PortfolioZip,
Age,
pub enum FileType {
CoverLetterPdf = 1,
PortfolioLetterPdf = 2,
PortfolioZip = 3,
Age = 4,
}
impl FileType {
pub fn index(&self) -> usize {
*self as usize
}
pub fn as_str(&self) -> &'static str {
match self {
FileType::CoverLetterPdf => "MOTIVACNI_DOPIS.pdf",
@ -23,6 +69,16 @@ impl FileType {
FileType::Age => "PORTFOLIO.age",
}
}
pub fn iter_cache() -> impl Iterator<Item = Self> {
[
FileType::CoverLetterPdf,
FileType::PortfolioLetterPdf,
FileType::PortfolioZip,
]
.iter()
.copied()
}
}
impl ToString for FileType {
@ -31,9 +87,43 @@ impl ToString for FileType {
}
}
impl Serialize for FileType {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
serializer.serialize_u32(self.index() as u32)
}
}
pub struct PortfolioService;
impl PortfolioService {
pub async fn get_submission_progress(candidate_id: i32) -> Result<SubmissionProgress, ServiceError> {
let path = Self::get_file_store_path().join(&candidate_id.to_string());
if !path.exists() {
return Err(ServiceError::CandidateNotFound);
}
let cache_path = path.join("cache");
if path.join(FileType::Age.as_str()).exists() {
return Ok(SubmissionProgress::Submitted);
}
let mut files = Vec::new();
for file in FileType::iter_cache() {
if cache_path.join(file.as_str()).exists() {
files.push(file);
}
}
match files.len() {
0 => Ok(SubmissionProgress::NoneInCache),
3 => Ok(SubmissionProgress::AllInCache),
_ => Ok(SubmissionProgress::SomeInCache(files)),
}
}
// Get root path or local directory
fn get_file_store_path() -> PathBuf {
dotenv::dotenv().ok();