mirror of
https://github.com/danbulant/Portfolio
synced 2026-06-24 17:11:49 +00:00
Merge pull request #53 from EETagent/submission_progress
Submission progress
This commit is contained in:
commit
e9ff241ea5
3 changed files with 118 additions and 7 deletions
|
|
@ -59,6 +59,7 @@ async fn start() -> Result<(), rocket::Error> {
|
||||||
routes::candidate::submit_portfolio,
|
routes::candidate::submit_portfolio,
|
||||||
routes::candidate::is_portfolio_prepared,
|
routes::candidate::is_portfolio_prepared,
|
||||||
routes::candidate::is_portfolio_submitted,
|
routes::candidate::is_portfolio_submitted,
|
||||||
|
routes::candidate::submission_progress,
|
||||||
routes::candidate::download_portfolio,
|
routes::candidate::download_portfolio,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ use std::net::SocketAddr;
|
||||||
use portfolio_core::candidate_details::ApplicationDetails;
|
use portfolio_core::candidate_details::ApplicationDetails;
|
||||||
use portfolio_core::services::application_service::ApplicationService;
|
use portfolio_core::services::application_service::ApplicationService;
|
||||||
use portfolio_core::services::candidate_service::CandidateService;
|
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 requests::LoginRequest;
|
||||||
use rocket::http::{Cookie, CookieJar, Status};
|
use rocket::http::{Cookie, CookieJar, Status};
|
||||||
use rocket::response::status::Custom;
|
use rocket::response::status::Custom;
|
||||||
|
|
@ -128,6 +128,26 @@ pub async fn upload_cover_letter(
|
||||||
Ok("Letter added".to_string())
|
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
|
// TODO: JSON
|
||||||
#[get["/is_cover_letter"]]
|
#[get["/is_cover_letter"]]
|
||||||
pub async fn is_cover_letter(session: CandidateAuth) -> Result<String, Custom<String>> {
|
pub async fn is_cover_letter(session: CandidateAuth) -> Result<String, Custom<String>> {
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,66 @@
|
||||||
use std::{path::{PathBuf, Path}};
|
use std::{path::{PathBuf, Path}};
|
||||||
|
|
||||||
use entity::candidate;
|
use entity::candidate;
|
||||||
use sea_orm::DbConn;
|
use sea_orm::{DbConn};
|
||||||
|
use serde::{Serialize, ser::{SerializeStruct}};
|
||||||
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
use tokio::io::{AsyncReadExt, AsyncWriteExt};
|
||||||
|
|
||||||
use crate::{error::ServiceError, Query, crypto};
|
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)]
|
#[derive(Copy, Clone)]
|
||||||
enum FileType {
|
pub enum FileType {
|
||||||
CoverLetterPdf,
|
CoverLetterPdf = 1,
|
||||||
PortfolioLetterPdf,
|
PortfolioLetterPdf = 2,
|
||||||
PortfolioZip,
|
PortfolioZip = 3,
|
||||||
Age,
|
Age = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FileType {
|
impl FileType {
|
||||||
|
pub fn index(&self) -> usize {
|
||||||
|
*self as usize
|
||||||
|
}
|
||||||
|
|
||||||
pub fn as_str(&self) -> &'static str {
|
pub fn as_str(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
FileType::CoverLetterPdf => "MOTIVACNI_DOPIS.pdf",
|
FileType::CoverLetterPdf => "MOTIVACNI_DOPIS.pdf",
|
||||||
|
|
@ -23,6 +69,16 @@ impl FileType {
|
||||||
FileType::Age => "PORTFOLIO.age",
|
FileType::Age => "PORTFOLIO.age",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn iter_cache() -> impl Iterator<Item = Self> {
|
||||||
|
[
|
||||||
|
FileType::CoverLetterPdf,
|
||||||
|
FileType::PortfolioLetterPdf,
|
||||||
|
FileType::PortfolioZip,
|
||||||
|
]
|
||||||
|
.iter()
|
||||||
|
.copied()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToString for FileType {
|
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;
|
pub struct PortfolioService;
|
||||||
impl 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
|
// Get root path or local directory
|
||||||
fn get_file_store_path() -> PathBuf {
|
fn get_file_store_path() -> PathBuf {
|
||||||
dotenv::dotenv().ok();
|
dotenv::dotenv().ok();
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue