add file proxy
This commit is contained in:
parent
652522da32
commit
b475854578
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -1112,7 +1112,7 @@ checksum = "25cbce373ec4653f1a01a31e8a5e5ec0c622dc27ff9c4e6606eefef5cbbed4a5"
|
||||
|
||||
[[package]]
|
||||
name = "ffplayout"
|
||||
version = "0.20.0-beta3"
|
||||
version = "0.20.0-beta4"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"clap",
|
||||
@ -1134,7 +1134,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ffplayout-api"
|
||||
version = "0.20.0-beta3"
|
||||
version = "0.20.0-beta4"
|
||||
dependencies = [
|
||||
"actix-files",
|
||||
"actix-multipart",
|
||||
@ -1167,7 +1167,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ffplayout-lib"
|
||||
version = "0.20.0-beta3"
|
||||
version = "0.20.0-beta4"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossbeam-channel",
|
||||
@ -3126,7 +3126,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tests"
|
||||
version = "0.20.0-beta3"
|
||||
version = "0.20.0-beta4"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"crossbeam-channel",
|
||||
|
@ -4,7 +4,7 @@ default-members = ["ffplayout-api", "ffplayout-engine", "tests"]
|
||||
resolver = "2"
|
||||
|
||||
[workspace.package]
|
||||
version = "0.20.0-beta3"
|
||||
version = "0.20.0-beta4"
|
||||
license = "GPL-3.0"
|
||||
repository = "https://github.com/ffplayout/ffplayout"
|
||||
authors = ["Jonathan Baecker <jonbae77@gmail.com>"]
|
||||
|
@ -8,11 +8,20 @@
|
||||
///
|
||||
/// For all endpoints an (Bearer) authentication is required.\
|
||||
/// `{id}` represent the channel id, and at default is 1.
|
||||
use std::{collections::HashMap, env, fs, path::PathBuf};
|
||||
use std::{collections::HashMap, env, fs, path::PathBuf, sync::{Arc, Mutex}};
|
||||
|
||||
use actix_files;
|
||||
use actix_multipart::Multipart;
|
||||
use actix_web::{delete, get, http::StatusCode, patch, post, put, web, HttpResponse, Responder};
|
||||
use actix_web::{
|
||||
delete, get,
|
||||
http::{
|
||||
header::{ContentDisposition, DispositionType},
|
||||
StatusCode,
|
||||
},
|
||||
patch, post, put, web, Error, HttpRequest, HttpResponse, Responder,
|
||||
};
|
||||
use actix_web_grants::{permissions::AuthDetails, proc_macro::has_any_role};
|
||||
|
||||
use argon2::{
|
||||
password_hash::{rand_core::OsRng, PasswordHash, SaltString},
|
||||
Argon2, PasswordHasher, PasswordVerifier,
|
||||
@ -37,7 +46,7 @@ use crate::utils::{
|
||||
},
|
||||
naive_date_time_from_str,
|
||||
playlist::{delete_playlist, generate_playlist, read_playlist, write_playlist},
|
||||
playout_config, read_log_file, read_playout_config, Role,
|
||||
read_log_file, read_playout_config, Role,
|
||||
};
|
||||
use crate::{
|
||||
auth::{create_jwt, Claims},
|
||||
@ -438,6 +447,7 @@ async fn update_playout_config(
|
||||
pool: web::Data<Pool<Sqlite>>,
|
||||
id: web::Path<i32>,
|
||||
data: web::Json<PlayoutConfig>,
|
||||
config: web::Data<Arc<Mutex<PlayoutConfig>>>,
|
||||
) -> Result<impl Responder, ServiceError> {
|
||||
if let Ok(channel) = handles::select_channel(&pool.into_inner(), &id).await {
|
||||
if let Ok(f) = std::fs::OpenOptions::new()
|
||||
@ -446,6 +456,7 @@ async fn update_playout_config(
|
||||
.open(channel.config_path)
|
||||
{
|
||||
serde_yaml::to_writer(f, &data).unwrap();
|
||||
*config.lock().unwrap() = data.into_inner();
|
||||
|
||||
return Ok("Update playout config success.");
|
||||
} else {
|
||||
@ -765,8 +776,10 @@ pub async fn gen_playlist(
|
||||
pool: web::Data<Pool<Sqlite>>,
|
||||
params: web::Path<(i32, String)>,
|
||||
data: Option<web::Json<PathsObj>>,
|
||||
global_config: web::Data<Arc<Mutex<PlayoutConfig>>>,
|
||||
) -> Result<impl Responder, ServiceError> {
|
||||
let (mut config, channel) = playout_config(&pool.into_inner(), ¶ms.0).await?;
|
||||
let channel = handles::select_channel(&pool.into_inner(), ¶ms.0).await?;
|
||||
let mut config = global_config.lock().unwrap();
|
||||
config.general.generate = Some(vec![params.1.clone()]);
|
||||
|
||||
if let Some(obj) = data {
|
||||
@ -785,7 +798,7 @@ pub async fn gen_playlist(
|
||||
config.general.template = obj.template.clone();
|
||||
}
|
||||
|
||||
match generate_playlist(config, channel.name).await {
|
||||
match generate_playlist(config.to_owned(), channel.name).await {
|
||||
Ok(playlist) => Ok(web::Json(playlist)),
|
||||
Err(e) => Err(e),
|
||||
}
|
||||
@ -919,6 +932,23 @@ async fn save_file(
|
||||
upload(&pool.into_inner(), *id, payload, &obj.path, false).await
|
||||
}
|
||||
|
||||
#[get("/file/{id}/{filename:.*}")]
|
||||
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
|
||||
async fn get_file(req: HttpRequest, config: web::Data<Arc<Mutex<PlayoutConfig>>>,) -> Result<actix_files::NamedFile, Error> {
|
||||
let storage_path = &config.lock().unwrap().storage.path;
|
||||
let file_path = req.match_info().query("filename");
|
||||
let (path, _, _) = norm_abs_path(storage_path, file_path);
|
||||
println!("{path:?}");
|
||||
|
||||
let file = actix_files::NamedFile::open(path)?;
|
||||
Ok(file
|
||||
.use_last_modified(true)
|
||||
.set_content_disposition(ContentDisposition {
|
||||
disposition: DispositionType::Attachment,
|
||||
parameters: vec![],
|
||||
}))
|
||||
}
|
||||
|
||||
/// **Import playlist**
|
||||
///
|
||||
/// Import text/m3u file and convert it to a playlist
|
||||
@ -935,11 +965,12 @@ async fn import_playlist(
|
||||
id: web::Path<i32>,
|
||||
payload: Multipart,
|
||||
obj: web::Query<ImportObj>,
|
||||
global_config: web::Data<Arc<Mutex<PlayoutConfig>>>,
|
||||
) -> Result<HttpResponse, ServiceError> {
|
||||
let file = obj.file.file_name().unwrap_or_default();
|
||||
let path = env::temp_dir().join(file);
|
||||
let (config, _) = playout_config(&pool.clone().into_inner(), &id).await?;
|
||||
let channel = handles::select_channel(&pool.clone().into_inner(), &id).await?;
|
||||
let config = global_config.lock().unwrap();
|
||||
|
||||
upload(&pool.into_inner(), *id, payload, &path, true).await?;
|
||||
import_file(&config, &obj.date, Some(channel.name), &path)?;
|
||||
@ -977,8 +1008,9 @@ async fn get_program(
|
||||
pool: web::Data<Pool<Sqlite>>,
|
||||
id: web::Path<i32>,
|
||||
obj: web::Query<ProgramObj>,
|
||||
global_config: web::Data<Arc<Mutex<PlayoutConfig>>>,
|
||||
) -> Result<impl Responder, ServiceError> {
|
||||
let (config, _) = playout_config(&pool.clone().into_inner(), &id).await?;
|
||||
let config = global_config.lock().unwrap();
|
||||
let start_sec = config.playlist.start_sec.unwrap();
|
||||
let mut days = 0;
|
||||
let mut program = vec![];
|
||||
|
@ -1,4 +1,4 @@
|
||||
use std::{path::Path, process::exit};
|
||||
use std::{path::Path, process::exit, sync::{Arc, Mutex}};
|
||||
|
||||
use actix_files::Files;
|
||||
use actix_web::{dev::ServiceRequest, middleware, web, App, Error, HttpMessage, HttpServer};
|
||||
@ -14,14 +14,7 @@ pub mod utils;
|
||||
|
||||
use api::{
|
||||
auth,
|
||||
routes::{
|
||||
add_channel, add_dir, add_preset, add_user, control_playout, del_playlist, delete_preset,
|
||||
file_browser, gen_playlist, get_all_channels, get_channel, get_log, get_playlist,
|
||||
get_playout_config, get_presets, get_program, get_user, import_playlist, login,
|
||||
media_current, media_last, media_next, move_rename, patch_channel, process_control, remove,
|
||||
remove_channel, save_file, save_playlist, send_text_message, update_playout_config,
|
||||
update_preset, update_user,
|
||||
},
|
||||
routes::*,
|
||||
};
|
||||
use db::{db_pool, models::LoginUser};
|
||||
use utils::{args_parse::Args, control::ProcessControl, db_path, init_config, run_args, Role};
|
||||
@ -92,6 +85,7 @@ async fn main() -> std::io::Result<()> {
|
||||
let addr = ip_port[0];
|
||||
let port = ip_port[1].parse::<u16>().unwrap();
|
||||
let engine_process = web::Data::new(ProcessControl::new());
|
||||
let global_config = Arc::new(Mutex::new(config));
|
||||
|
||||
info!("running ffplayout API, listen on {conn}");
|
||||
|
||||
@ -99,9 +93,11 @@ async fn main() -> std::io::Result<()> {
|
||||
HttpServer::new(move || {
|
||||
let auth = HttpAuthentication::bearer(validator);
|
||||
let db_pool = web::Data::new(pool.clone());
|
||||
let global = web::Data::new(global_config.clone());
|
||||
|
||||
App::new()
|
||||
.app_data(db_pool)
|
||||
.app_data(global)
|
||||
.app_data(engine_process.clone())
|
||||
.wrap(middleware::Logger::default())
|
||||
.service(login)
|
||||
@ -138,6 +134,7 @@ async fn main() -> std::io::Result<()> {
|
||||
.service(move_rename)
|
||||
.service(remove)
|
||||
.service(save_file)
|
||||
.service(get_file)
|
||||
.service(import_playlist)
|
||||
.service(get_program),
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user