catchup
parent
6d939efbbf
commit
290041e367
39
src/main.rs
39
src/main.rs
|
@ -6,7 +6,7 @@ use axum::{
|
||||||
http::{Request, Response, StatusCode},
|
http::{Request, Response, StatusCode},
|
||||||
middleware::{self, Next},
|
middleware::{self, Next},
|
||||||
response::{Html, IntoResponse, Redirect},
|
response::{Html, IntoResponse, Redirect},
|
||||||
routing::{delete, get, post},
|
routing::{get, post},
|
||||||
Json, Router, TypedHeader,
|
Json, Router, TypedHeader,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -91,8 +91,7 @@ async fn main() -> io::Result<()> {
|
||||||
.route("/records", get(records))
|
.route("/records", get(records))
|
||||||
.route("/records/links", get(records_links))
|
.route("/records/links", get(records_links))
|
||||||
.route("/download/:id", get(download))
|
.route("/download/:id", get(download))
|
||||||
.route("/link/:id", get(link))
|
.route("/link/:id", get(link).delete(link_delete))
|
||||||
.route("/link/:id", delete(link_delete))
|
|
||||||
.route("/link/:id/remaining", get(remaining))
|
.route("/link/:id/remaining", get(remaining))
|
||||||
.layer(DefaultBodyLimit::disable())
|
.layer(DefaultBodyLimit::disable())
|
||||||
.layer(RequestBodyLimitLayer::new(
|
.layer(RequestBodyLimitLayer::new(
|
||||||
|
@ -178,7 +177,10 @@ async fn link(
|
||||||
{
|
{
|
||||||
let mut records = state.records.lock().await;
|
let mut records = state.records.lock().await;
|
||||||
|
|
||||||
if let Some(record) = records.get_mut(&id) {
|
if let Some(record) = records
|
||||||
|
.get_mut(&id)
|
||||||
|
.filter(|record| record.can_be_downloaded())
|
||||||
|
{
|
||||||
if record.can_be_downloaded() {
|
if record.can_be_downloaded() {
|
||||||
return Ok(Html(leptos::ssr::render_to_string({
|
return Ok(Html(leptos::ssr::render_to_string({
|
||||||
let record = record.clone();
|
let record = record.clone();
|
||||||
|
@ -292,11 +294,10 @@ async fn upload_to_zip(
|
||||||
async fn download(
|
async fn download(
|
||||||
axum::extract::Path(id): axum::extract::Path<String>,
|
axum::extract::Path(id): axum::extract::Path<String>,
|
||||||
headers: HeaderMap,
|
headers: HeaderMap,
|
||||||
State(mut state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
) -> Result<axum::response::Response, (StatusCode, String)> {
|
) -> Result<axum::response::Response, (StatusCode, String)> {
|
||||||
{
|
{
|
||||||
let mut records = state.records.lock().await;
|
let mut records = state.records.lock().await;
|
||||||
tracing::info!("{headers:?}");
|
|
||||||
if headers.get("hx-request").is_some() {
|
if headers.get("hx-request").is_some() {
|
||||||
return Ok(axum::http::Response::builder()
|
return Ok(axum::http::Response::builder()
|
||||||
.header("HX-Redirect", format!("/download/{id}"))
|
.header("HX-Redirect", format!("/download/{id}"))
|
||||||
|
@ -306,23 +307,23 @@ async fn download(
|
||||||
.into_response());
|
.into_response());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(record) = records.get_mut(&id) {
|
if let Some(record) = records
|
||||||
if record.can_be_downloaded() {
|
.get_mut(&id)
|
||||||
record.downloads += 1;
|
.filter(|record| record.can_be_downloaded())
|
||||||
|
{
|
||||||
|
record.downloads += 1;
|
||||||
|
|
||||||
let file = tokio::fs::File::open(&record.file).await.unwrap();
|
let file = tokio::fs::File::open(&record.file).await.unwrap();
|
||||||
|
|
||||||
return Ok(axum::response::Response::builder()
|
return Ok(axum::response::Response::builder()
|
||||||
.header("Content-Type", "application/zip")
|
.header("Content-Type", "application/zip")
|
||||||
.body(StreamBody::new(ReaderStream::new(file)))
|
.body(StreamBody::new(ReaderStream::new(file)))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into_response());
|
.into_response());
|
||||||
}
|
} else {
|
||||||
|
records.remove_record(&id).await.unwrap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This....
|
|
||||||
state.remove_record(&id).await.unwrap();
|
|
||||||
|
|
||||||
Ok(Redirect::to("/404.html").into_response())
|
Ok(Redirect::to("/404.html").into_response())
|
||||||
}
|
}
|
||||||
|
|
30
src/state.rs
30
src/state.rs
|
@ -1,5 +1,6 @@
|
||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::{hash_map::Entry, HashMap},
|
||||||
|
io::ErrorKind,
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
@ -72,26 +73,25 @@ pub trait AsyncRemoveRecord {
|
||||||
impl AsyncRemoveRecord for AppState {
|
impl AsyncRemoveRecord for AppState {
|
||||||
async fn remove_record(&mut self, id: &String) -> Result<(), std::io::Error> {
|
async fn remove_record(&mut self, id: &String) -> Result<(), std::io::Error> {
|
||||||
let mut records = self.records.lock().await;
|
let mut records = self.records.lock().await;
|
||||||
|
records.remove_record(id).await
|
||||||
if let Some(record) = records.get_mut(id) {
|
|
||||||
tokio::fs::remove_file(&record.file).await?;
|
|
||||||
records.remove(id);
|
|
||||||
cache::write_to_cache(&records).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl AsyncRemoveRecord for HashMap<String, UploadRecord> {
|
impl AsyncRemoveRecord for HashMap<String, UploadRecord> {
|
||||||
async fn remove_record(&mut self, id: &String) -> Result<(), std::io::Error> {
|
async fn remove_record(&mut self, id: &String) -> Result<(), std::io::Error> {
|
||||||
if let Some(record) = self.get_mut(id) {
|
match self.entry(id.clone()) {
|
||||||
tokio::fs::remove_file(&record.file).await?;
|
Entry::Occupied(entry) => {
|
||||||
self.remove(id);
|
tokio::fs::remove_file(&entry.get().file).await?;
|
||||||
cache::write_to_cache(&self).await?;
|
entry.remove_entry();
|
||||||
}
|
cache::write_to_cache(&self).await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
}
|
||||||
|
Entry::Vacant(_) => Err(std::io::Error::new(
|
||||||
|
ErrorKind::Other,
|
||||||
|
"No UploadRecord Found",
|
||||||
|
)),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -91,7 +91,7 @@ pub fn LinkView(cx: Scope, id: String, record: UploadRecord) -> impl IntoView {
|
||||||
cx,
|
cx,
|
||||||
<div class="column-container">
|
<div class="column-container">
|
||||||
<div class="link-wrapper">
|
<div class="link-wrapper">
|
||||||
<a id="link" hx-get="/download/{id}" href="/download/{id}">Download Now!</a>
|
<a id="link" href="/download/{id}">Download Now!</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="link-wrapper" hx-get="/link/{id}/remaining" hx-trigger="click from:#link delay:0.2s, every 10s" >
|
<div class="link-wrapper" hx-get="/link/{id}/remaining" hx-trigger="click from:#link delay:0.2s, every 10s" >
|
||||||
|
|
Loading…
Reference in New Issue