support path list for playlist generation, #258
This commit is contained in:
parent
af985cb351
commit
e752a7a951
@ -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(), ¶ms.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),
|
||||
}
|
||||
|
@ -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()
|
||||
|
@ -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())
|
||||
|
@ -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(
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -32,32 +32,43 @@ 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() {
|
||||
error!(
|
||||
"Path not exists: <b><magenta>{}</></b>",
|
||||
config.storage.path
|
||||
);
|
||||
exit(1);
|
||||
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 entry in WalkDir::new(config.storage.path.clone())
|
||||
.into_iter()
|
||||
.flat_map(|e| e.ok())
|
||||
.filter(|f| f.path().is_file())
|
||||
{
|
||||
if include_file(config.clone(), entry.path()) {
|
||||
let media = Media::new(0, &entry.path().to_string_lossy(), false);
|
||||
media_list.push(media);
|
||||
for path in &path_list {
|
||||
if !Path::new(path).is_dir() {
|
||||
error!(
|
||||
"Path not exists: <b><magenta>{}</></b>",
|
||||
path
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
for entry in WalkDir::new(path.clone())
|
||||
.into_iter()
|
||||
.flat_map(|e| e.ok())
|
||||
.filter(|f| f.path().is_file())
|
||||
{
|
||||
if include_file(config.clone(), entry.path()) {
|
||||
let media = Media::new(0, &entry.path().to_string_lossy(), false);
|
||||
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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user