support path list for playlist generation, #258

This commit is contained in:
jb-alvarado 2023-01-22 14:17:51 +01:00
parent af985cb351
commit e752a7a951
7 changed files with 73 additions and 30 deletions

View File

@ -34,7 +34,7 @@ use crate::utils::{
errors::ServiceError,
files::{
browser, create_directory, remove_file_or_folder, rename_file, upload, MoveObject,
PathObject,
PathObject, norm_abs_path,
},
naive_date_time_from_str,
playlist::{delete_playlist, generate_playlist, read_playlist, write_playlist},
@ -72,6 +72,12 @@ struct FileObj {
path: String,
}
#[derive(Debug, Default, Deserialize, Serialize)]
pub struct PathsObj {
#[serde(default)]
paths: Vec<String>,
}
#[derive(Debug, Deserialize, Serialize)]
pub struct ImportObj {
#[serde(default)]
@ -734,16 +740,33 @@ pub async fn save_playlist(
/// A new playlist will be generated and response.
///
/// ```BASH
/// curl -X GET http://127.0.0.1:8787/api/playlist/1/generate/2022-06-20
/// curl -X POST http://127.0.0.1:8787/api/playlist/1/generate/2022-06-20
/// -H 'Content-Type: application/json' -H 'Authorization: Bearer <TOKEN>'
/// /// -- data '{ "paths": [<list of paths>] }' # <- data is optional
/// ```
#[get("/playlist/{id}/generate/{date}")]
#[post("/playlist/{id}/generate/{date}")]
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
pub async fn gen_playlist(
pool: web::Data<Pool<Sqlite>>,
params: web::Path<(i32, String)>,
data: Option<web::Json<PathsObj>>,
) -> Result<impl Responder, ServiceError> {
match generate_playlist(&pool.into_inner(), params.0, params.1.clone()).await {
let (mut config, channel) = playout_config(&pool.into_inner(), &params.0).await?;
config.general.generate = Some(vec![params.1.clone()]);
if let Some(obj) = data {
let mut path_list = vec![];
for path in &obj.paths {
let (p, _, _) = norm_abs_path(&config.storage.path, &path);
path_list.push(p.to_string_lossy().to_string());
}
config.storage.paths = path_list;
}
match generate_playlist(config, channel.name).await {
Ok(playlist) => Ok(web::Json(playlist)),
Err(e) => Err(e),
}

View File

@ -49,7 +49,7 @@ pub struct VideoFile {
///
/// This function takes care, that it is not possible to break out from root_path.
/// It also gives alway a relative path back.
fn norm_abs_path(root_path: &str, input_path: &str) -> (PathBuf, String, String) {
pub fn norm_abs_path(root_path: &str, input_path: &str) -> (PathBuf, String, String) {
let mut path = PathBuf::from(root_path);
let path_relative = RelativePath::new(root_path)
.normalize()

View File

@ -5,7 +5,7 @@ use sqlx::{Pool, Sqlite};
use crate::utils::{errors::ServiceError, playout_config};
use ffplayout_lib::utils::{
generate_playlist as playlist_generator, json_reader, json_writer, JsonPlaylist,
generate_playlist as playlist_generator, json_reader, json_writer, JsonPlaylist, PlayoutConfig,
};
pub async fn read_playlist(
@ -78,14 +78,10 @@ pub async fn write_playlist(
}
pub async fn generate_playlist(
conn: &Pool<Sqlite>,
id: i32,
date: String,
config: PlayoutConfig,
channel: String,
) -> Result<JsonPlaylist, ServiceError> {
let (mut config, channel) = playout_config(conn, &id).await?;
config.general.generate = Some(vec![date.clone()]);
match playlist_generator(&config, Some(channel.name)) {
match playlist_generator(&config, Some(channel)) {
Ok(playlists) => {
if !playlists.is_empty() {
Ok(playlists[0].clone())

View File

@ -27,6 +27,13 @@ pub struct Args {
)]
pub generate: Option<Vec<String>>,
#[clap(
long,
help = "Optional path list for playlist generations",
multiple_values = true
)]
pub paths: Option<Vec<String>>,
#[clap(short = 'm', long, help = "Playing mode: folder, playlist")]
pub play_mode: Option<ProcessMode>,
@ -46,7 +53,7 @@ pub struct Args {
)]
pub import: Option<String>,
#[clap(short, long, help = "Path from playlist")]
#[clap(short, long, help = "Path to playlist, or playlist root folder.")]
pub playlist: Option<String>,
#[clap(

View File

@ -38,6 +38,10 @@ pub fn get_config(args: Args) -> PlayoutConfig {
config.general.generate = Some(gen);
}
if let Some(paths) = args.paths {
config.storage.paths = paths;
}
if let Some(log_path) = args.log {
if Path::new(&log_path).is_dir() {
config.logging.log_to_file = true;

View File

@ -213,6 +213,8 @@ pub struct Playlist {
pub struct Storage {
pub help_text: String,
pub path: String,
#[serde(skip_serializing, skip_deserializing)]
pub paths: Vec<String>,
pub filler_clip: String,
pub extensions: Vec<String>,
pub shuffle: bool,

View File

@ -32,18 +32,28 @@ impl FolderSource {
current_list: Arc<Mutex<Vec<Media>>>,
global_index: Arc<AtomicUsize>,
) -> Self {
let mut path_list = vec![];
let mut media_list = vec![];
let mut index: usize = 0;
if !Path::new(&config.storage.path).is_dir() {
if config.general.generate.is_some() && !config.storage.paths.is_empty() {
for path in &config.storage.paths {
path_list.push(path.clone())
}
} else {
path_list.push(config.storage.path.clone())
}
for path in &path_list {
if !Path::new(path).is_dir() {
error!(
"Path not exists: <b><magenta>{}</></b>",
config.storage.path
path
);
exit(1);
}
for entry in WalkDir::new(config.storage.path.clone())
for entry in WalkDir::new(path.clone())
.into_iter()
.flat_map(|e| e.ok())
.filter(|f| f.path().is_file())
@ -53,11 +63,12 @@ impl FolderSource {
media_list.push(media);
}
}
}
if media_list.is_empty() {
error!(
"no playable files found under: <b><magenta>{}</></b>",
config.storage.path
"no playable files found under: <b><magenta>{:?}</></b>",
path_list
);
exit(1);