Pour tout problème contactez-nous par mail : support@froggit.fr | La FAQ :grey_question: | Rejoignez-nous sur le Chat :speech_balloon:

Skip to content
Snippets Groups Projects
Commit ddcd7ff2 authored by Pierre Jarriges's avatar Pierre Jarriges
Browse files

admin delete files

parent f33c4356
No related branches found
No related tags found
1 merge request!9Upload files
"use strict"; "use strict";
const { fetch_post_file } = require("../xhr"); const { fetch_post_file, fetch_delete_static_file } = require("../xhr");
class FilesIndexView { class FilesIndexView {
constructor(index) { constructor(params) {
this.index = index; this.params = params;
this.show_category = Object.keys(this.index)[0]; this.show_category = Object.keys(this.params.get_files_index())[0];
this.id = "files-index-view"; this.id = "files-index-view";
} }
...@@ -34,41 +34,63 @@ class FilesIndexView { ...@@ -34,41 +34,63 @@ class FilesIndexView {
} }
get_item_view(item) { get_item_view(item) {
switch (this.show_category) { const get_link = () => {
case "images": switch (this.show_category) {
return { case "images":
tag: "a", return {
href: item, tag: "a",
target: "_blank", href: item,
style_rules: { target: "_blank",
backgroundImage: `url(${item})`, style_rules: {
backgroundRepeat: "no-repeat", backgroundImage: `url(${item})`,
backgroundSize: "cover", backgroundRepeat: "no-repeat",
backgroundPosition: "center", backgroundSize: "cover",
width: "100px", backgroundPosition: "center",
height: "100px", width: "100px",
display: "block" height: "100px",
} display: "block"
}
case "sounds":
return {
tag: "a",
href: item,
target: "_blank",
contents: [
{
tag: "audio",
src: item
} }
] }
} case "sounds":
default: return {
return { tag: "a",
tag: "a", href: item,
href: item, target: "_blank",
target: "_blank", contents: [
contents: item {
tag: "audio",
src: item
}
]
}
default:
return {
tag: "a",
href: item,
target: "_blank",
contents: item
}
}
}
return {
tag: "div",
contents: [
get_link(),
{
tag: "button",
contents: "DEL",
onclick: () => {
const rev_split = item.split("/").reverse();
const filename = rev_split.shift();
const category = rev_split.shift();
const dir = rev_split[0] === "uploads" ? "uploads" : "base";
fetch_delete_static_file(dir, category, filename).then(res => {
this.params.refresh_index(this.refresh.bind(this));
}).catch(err => console.log(err))
}
} }
]
} }
} }
...@@ -77,6 +99,7 @@ class FilesIndexView { ...@@ -77,6 +99,7 @@ class FilesIndexView {
} }
render() { render() {
const files_index = this.params.get_files_index();
return { return {
tag: "div", tag: "div",
id: this.id, id: this.id,
...@@ -89,7 +112,7 @@ class FilesIndexView { ...@@ -89,7 +112,7 @@ class FilesIndexView {
margin: 0, margin: 0,
padding: 0, padding: 0,
}, },
contents: Object.keys(this.index).map(cat => { contents: Object.keys(files_index).map(cat => {
return { return {
tag: "li", tag: "li",
style_rules: { style_rules: {
...@@ -109,7 +132,7 @@ class FilesIndexView { ...@@ -109,7 +132,7 @@ class FilesIndexView {
{ {
tag: "ul", tag: "ul",
style_rules: this.get_files_list_style(this.show_category), style_rules: this.get_files_list_style(this.show_category),
contents: this.index[this.show_category].map(item => { contents: files_index[this.show_category].map(item => {
return { return {
tag: "li", tag: "li",
contents: [ contents: [
...@@ -126,24 +149,32 @@ class FilesIndexView { ...@@ -126,24 +149,32 @@ class FilesIndexView {
class ManageFilesForm { class ManageFilesForm {
constructor(params) { constructor(params) {
this.params = params; this.params = params;
this.id = "static-file-manager-view";
} }
render_index_view() { render_index_view() {
return new FilesIndexView(this.params.files_index).render() return new FilesIndexView(this.params).render()
}
refresh() {
obj2htm.subRender(this.render(), document.getElementById(this.id), { mode: "replace" })
} }
render() { render() {
return { return {
tag: "div", tag: "div",
id: this.id,
contents: [ contents: [
this.render_index_view(), this.render_index_view(),
{ {
tag: "form", tag: "form",
style_rules: { border: "1px solid black" }, style_rules: { border: "1px solid black" },
enctype: "multipart/form-data", enctype: "multipart/form-data",
onsubmit: function (e) { onsubmit: e => {
e.preventDefault(); e.preventDefault();
fetch_post_file(e.target).then(res => console.log(res)).catch(err => console.log(err)); fetch_post_file(e.target).then(() => {
this.params.refresh_index(this.refresh.bind(this))
}).catch(err => console.log(err));
}, },
contents: [ contents: [
{ tag: "input", name: "file", type: "file", multiple: true }, { tag: "input", name: "file", type: "file", multiple: true },
......
const { fetch_post_file, fetch_static_files_index } = require("../xhr"); const { fetch_static_files_index } = require("../xhr");
const CreateArticleForm = require("./create-article-form"); const CreateArticleForm = require("./create-article-form");
const ManageFilesForm = require("./manage-files-form"); const ManageFilesForm = require("./manage-files-form");
const UpdateArticleForm = require("./update-article-form"); const UpdateArticleForm = require("./update-article-form");
...@@ -12,7 +12,7 @@ class RootComponent { ...@@ -12,7 +12,7 @@ class RootComponent {
static_files_index: {} static_files_index: {}
}; };
this.fetch_files_index(); this.fetch_files_index(obj2htm.renderCycle.bind(obj2htm));
} }
build_index_object(files_urls) { build_index_object(files_urls) {
...@@ -24,7 +24,7 @@ class RootComponent { ...@@ -24,7 +24,7 @@ class RootComponent {
}, {}); }, {});
} }
fetch_files_index() { fetch_files_index(cb) {
fetch_static_files_index() fetch_static_files_index()
.then(files => .then(files =>
this.state.static_files_index = this.build_index_object(files) this.state.static_files_index = this.build_index_object(files)
...@@ -32,7 +32,7 @@ class RootComponent { ...@@ -32,7 +32,7 @@ class RootComponent {
.catch(err => console.log(err)) .catch(err => console.log(err))
.finally(() => { .finally(() => {
this.state.loading_index = false; this.state.loading_index = false;
obj2htm.renderCycle(); cb();
}); });
} }
...@@ -49,7 +49,7 @@ class RootComponent { ...@@ -49,7 +49,7 @@ class RootComponent {
case "update": case "update":
return new UpdateArticleForm({ files_index }).render(); return new UpdateArticleForm({ files_index }).render();
case "files": case "files":
return new ManageFilesForm({ files_index }).render() return new ManageFilesForm({ get_files_index: () => this.state.static_files_index, refresh_index: this.fetch_files_index.bind(this) }).render()
default: default:
return undefined; return undefined;
} }
......
...@@ -117,7 +117,6 @@ function fetch_post_file(form) { ...@@ -117,7 +117,6 @@ function fetch_post_file(form) {
} }
}).catch(err => reject(err)) }).catch(err => reject(err))
}) })
} }
function fetch_static_files_index() { function fetch_static_files_index() {
...@@ -132,6 +131,22 @@ function fetch_static_files_index() { ...@@ -132,6 +131,22 @@ function fetch_static_files_index() {
}) })
} }
function fetch_delete_static_file(dir, category, filename) {
return new Promise((resolve, reject) => {
fetch(`/delete-file/${dir}/${category}/${filename}`, {
credentials: 'include',
method: "DELETE",
}).then(async res => {
const text = await res.text();
if (res.status >= 400 && res.status < 600) {
reject(text)
} else {
resolve(text);
}
}).catch(err => reject(err))
})
}
module.exports = { module.exports = {
fetch_article, fetch_article,
...@@ -142,4 +157,5 @@ module.exports = { ...@@ -142,4 +157,5 @@ module.exports = {
fetch_all_articles, fetch_all_articles,
fetch_post_file, fetch_post_file,
fetch_static_files_index, fetch_static_files_index,
fetch_delete_static_file,
} }
\ No newline at end of file
...@@ -43,7 +43,6 @@ impl StaticFilesIndex { ...@@ -43,7 +43,6 @@ impl StaticFilesIndex {
} }
pub fn rebuild(&mut self, env: &Env) { pub fn rebuild(&mut self, env: &Env) {
// let root = env.public_dir.join("assets");
let public_dir = StaticFilesIndex::get_public_dir(env); let public_dir = StaticFilesIndex::get_public_dir(env);
let root = public_dir.join("assets"); let root = public_dir.join("assets");
self.0 = Vec::new(); self.0 = Vec::new();
...@@ -55,6 +54,15 @@ impl StaticFilesIndex { ...@@ -55,6 +54,15 @@ impl StaticFilesIndex {
StaticFilesIndex::_push_path(path, &mut self.0, &strip_from); StaticFilesIndex::_push_path(path, &mut self.0, &strip_from);
} }
pub fn remove_path(&mut self, strpath: String) {
self.0 = self
.0
.iter()
.filter(|url| strpath != **url)
.map(|s| s.to_owned())
.collect();
}
pub fn get_index(&self) -> Vec<String> { pub fn get_index(&self) -> Vec<String> {
self.0.clone() self.0.clone()
} }
......
...@@ -96,6 +96,7 @@ async fn main() -> std::io::Result<()> { ...@@ -96,6 +96,7 @@ async fn main() -> std::io::Result<()> {
.service(get_all_articles) .service(get_all_articles)
.service(post_files) .service(post_files)
.service(get_static_files_index) .service(get_static_files_index)
.service(delete_static_file)
///////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////
// STANDARD FILES /////////////////////////////////////////////////////////////////////////////////////////// // STANDARD FILES ///////////////////////////////////////////////////////////////////////////////////////////
.service(resource("/favicon.ico").route(get().to(favicon))) .service(resource("/favicon.ico").route(get().to(favicon)))
......
use crate::{core::static_files::*, middleware::AuthenticatedAdminMiddleware, AppState}; use crate::{core::static_files::*, middleware::AuthenticatedAdminMiddleware, AppState};
use actix_multipart::Multipart; use actix_multipart::Multipart;
use actix_web::{get, post, web::Data, HttpRequest, HttpResponse, Responder}; use actix_web::{
delete, get, post,
web::{Data, Path},
HttpRequest, HttpResponse, Responder,
};
use futures::StreamExt; use futures::StreamExt;
use std::{ use std::{
fs::{remove_file, File}, fs::{remove_file, File},
...@@ -118,6 +122,40 @@ async fn get_static_files_index( ...@@ -118,6 +122,40 @@ async fn get_static_files_index(
) )
} }
#[delete("/delete-file/{dir}/{category}/{filename}")]
async fn delete_static_file(
app_state: Data<AppState>,
static_files_index: Data<std::sync::Mutex<StaticFilesIndex>>,
fileinfo: Path<(String, String, String)>,
middleware: Data<AuthenticatedAdminMiddleware<'_>>,
req: HttpRequest,
) -> impl Responder {
if middleware.exec(&app_state, &req, None).await.is_err() {
return HttpResponse::Unauthorized().finish();
}
let (dir, cat, fname) = fileinfo.into_inner();
let fpath = std::path::PathBuf::from(cat).join(fname);
let fbasedir = {
let p = std::path::PathBuf::from("assets");
if dir == "uploads" {
p.join("uploads")
} else {
p
}
};
match remove_file(app_state.env.public_dir.join(&fbasedir).join(&fpath)) {
Ok(_) => {
let indexed_url = std::path::PathBuf::from("/").join(&fbasedir).join(&fpath);
let mut files_index = static_files_index.lock().unwrap();
files_index.remove_path(indexed_url.to_str().unwrap().to_owned());
HttpResponse::Accepted().body("File was deleted")
}
Err(e) => HttpResponse::InternalServerError().body(format!("Error deleting file {:?}", e)),
}
}
// EXAMPLE FROM ACTIX REPO (using threadpool) // EXAMPLE FROM ACTIX REPO (using threadpool)
// use futures::TryStreamExt; // use futures::TryStreamExt;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment