update config
This commit is contained in:
parent
0dbdd1f46e
commit
39c51e9f80
@ -1 +1 @@
|
|||||||
Subproject commit 8d63cc4f85f3cbd530d509d74494b6fefbb9bf2c
|
Subproject commit 6225a2725465e5ff0d572b368346047e16d1be72
|
@ -8,7 +8,11 @@
|
|||||||
///
|
///
|
||||||
/// For all endpoints an (Bearer) authentication is required.\
|
/// For all endpoints an (Bearer) authentication is required.\
|
||||||
/// `{id}` represent the channel id, and at default is 1.
|
/// `{id}` represent the channel id, and at default is 1.
|
||||||
use std::{env, path::PathBuf, sync::Mutex};
|
use std::{
|
||||||
|
env,
|
||||||
|
path::PathBuf,
|
||||||
|
sync::{atomic::Ordering, Mutex},
|
||||||
|
};
|
||||||
|
|
||||||
use actix_files;
|
use actix_files;
|
||||||
use actix_multipart::Multipart;
|
use actix_multipart::Multipart;
|
||||||
@ -34,13 +38,15 @@ use serde::{Deserialize, Serialize};
|
|||||||
use sqlx::{Pool, Sqlite};
|
use sqlx::{Pool, Sqlite};
|
||||||
use tokio::fs;
|
use tokio::fs;
|
||||||
|
|
||||||
use crate::api::auth::{create_jwt, Claims};
|
|
||||||
use crate::player::utils::{
|
use crate::player::utils::{
|
||||||
get_data_map, get_date_range, import::import_file, sec_to_time, time_to_sec, JsonPlaylist,
|
get_data_map, get_date_range, import::import_file, sec_to_time, time_to_sec, JsonPlaylist,
|
||||||
};
|
};
|
||||||
use crate::utils::{
|
use crate::utils::{
|
||||||
channels::{create_channel, delete_channel},
|
channels::{create_channel, delete_channel},
|
||||||
config::{PlayoutConfig, Template},
|
config::{
|
||||||
|
string_to_log_level, string_to_output_mode, string_to_processing_mode, PlayoutConfig,
|
||||||
|
Template,
|
||||||
|
},
|
||||||
control::{control_state, send_message, ControlParams, Process, ProcessCtl},
|
control::{control_state, send_message, ControlParams, Process, ProcessCtl},
|
||||||
errors::ServiceError,
|
errors::ServiceError,
|
||||||
files::{
|
files::{
|
||||||
@ -52,6 +58,10 @@ use crate::utils::{
|
|||||||
public_path, read_log_file, system, Role, TextFilter,
|
public_path, read_log_file, system, Role, TextFilter,
|
||||||
};
|
};
|
||||||
use crate::vec_strings;
|
use crate::vec_strings;
|
||||||
|
use crate::{
|
||||||
|
api::auth::{create_jwt, Claims},
|
||||||
|
db::models::Configuration,
|
||||||
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
db::{
|
db::{
|
||||||
handles,
|
handles,
|
||||||
@ -493,7 +503,6 @@ async fn get_playout_config(
|
|||||||
) -> Result<impl Responder, ServiceError> {
|
) -> Result<impl Responder, ServiceError> {
|
||||||
let manager = controllers.lock().unwrap().get(*id).unwrap();
|
let manager = controllers.lock().unwrap().get(*id).unwrap();
|
||||||
let config = manager.config.lock().unwrap().clone();
|
let config = manager.config.lock().unwrap().clone();
|
||||||
// let config = PlayoutConfig::new(&pool.into_inner(), *id).await;
|
|
||||||
|
|
||||||
Ok(web::Json(config))
|
Ok(web::Json(config))
|
||||||
}
|
}
|
||||||
@ -509,15 +518,80 @@ async fn get_playout_config(
|
|||||||
async fn update_playout_config(
|
async fn update_playout_config(
|
||||||
pool: web::Data<Pool<Sqlite>>,
|
pool: web::Data<Pool<Sqlite>>,
|
||||||
id: web::Path<i32>,
|
id: web::Path<i32>,
|
||||||
_data: web::Json<PlayoutConfig>,
|
data: web::Json<PlayoutConfig>,
|
||||||
|
controllers: web::Data<Mutex<ChannelController>>,
|
||||||
) -> Result<impl Responder, ServiceError> {
|
) -> Result<impl Responder, ServiceError> {
|
||||||
if let Ok(_channel) = handles::select_channel(&pool.into_inner(), &id).await {
|
let manager = controllers.lock().unwrap().get(*id).unwrap();
|
||||||
// TODO: update config
|
let mut config = manager.config.lock().unwrap();
|
||||||
|
let id = config.general.id;
|
||||||
|
let channel_id = config.general.channel_id;
|
||||||
|
let db_config = Configuration::from(id, channel_id, data.into_inner());
|
||||||
|
|
||||||
return Ok("Update playout config success.");
|
if let Err(e) = handles::update_configuration(&pool.into_inner(), db_config.clone()).await {
|
||||||
};
|
return Err(ServiceError::Conflict(format!("{e}")));
|
||||||
|
}
|
||||||
|
|
||||||
Err(ServiceError::InternalServerError)
|
config.general.stop_threshold = db_config.stop_threshold;
|
||||||
|
config.mail.subject = db_config.subject;
|
||||||
|
config.mail.smtp_server = db_config.smtp_server;
|
||||||
|
config.mail.starttls = db_config.starttls;
|
||||||
|
config.mail.sender_addr = db_config.sender_addr;
|
||||||
|
config.mail.sender_pass = db_config.sender_pass;
|
||||||
|
config.mail.recipient = db_config.recipient;
|
||||||
|
config.mail.mail_level = string_to_log_level(db_config.mail_level);
|
||||||
|
config.mail.interval = db_config.interval as u64;
|
||||||
|
config.logging.ffmpeg_level = db_config.ffmpeg_level;
|
||||||
|
config.logging.ingest_level = db_config.ingest_level;
|
||||||
|
config.logging.detect_silence = db_config.detect_silence;
|
||||||
|
config.logging.ignore_lines = db_config
|
||||||
|
.ignore_lines
|
||||||
|
.split(";")
|
||||||
|
.map(|l| l.to_string())
|
||||||
|
.collect();
|
||||||
|
config.processing.mode = string_to_processing_mode(db_config.processing_mode);
|
||||||
|
config.processing.audio_only = db_config.audio_only;
|
||||||
|
config.processing.audio_track_index = db_config.audio_track_index;
|
||||||
|
config.processing.copy_audio = db_config.copy_audio;
|
||||||
|
config.processing.copy_video = db_config.copy_video;
|
||||||
|
config.processing.width = db_config.width;
|
||||||
|
config.processing.height = db_config.height;
|
||||||
|
config.processing.aspect = db_config.aspect;
|
||||||
|
config.processing.fps = db_config.fps;
|
||||||
|
config.processing.add_logo = db_config.add_logo;
|
||||||
|
config.processing.logo = db_config.logo;
|
||||||
|
config.processing.logo_scale = db_config.logo_scale;
|
||||||
|
config.processing.logo_opacity = db_config.logo_opacity;
|
||||||
|
config.processing.logo_position = db_config.logo_position;
|
||||||
|
config.processing.audio_tracks = db_config.audio_tracks;
|
||||||
|
config.processing.audio_channels = db_config.audio_channels;
|
||||||
|
config.processing.volume = db_config.volume;
|
||||||
|
config.processing.custom_filter = db_config.decoder_filter;
|
||||||
|
config.ingest.enable = db_config.ingest_enable;
|
||||||
|
config.ingest.input_param = db_config.ingest_param;
|
||||||
|
config.ingest.custom_filter = db_config.ingest_filter;
|
||||||
|
config.playlist.path = PathBuf::from(db_config.playlist_path);
|
||||||
|
config.playlist.day_start = db_config.day_start;
|
||||||
|
config.playlist.length = db_config.length;
|
||||||
|
config.playlist.infinit = db_config.infinit;
|
||||||
|
config.storage.path = PathBuf::from(db_config.storage_path);
|
||||||
|
config.storage.filler = PathBuf::from(db_config.filler);
|
||||||
|
config.storage.extensions = db_config
|
||||||
|
.extensions
|
||||||
|
.split(";")
|
||||||
|
.map(|l| l.to_string())
|
||||||
|
.collect();
|
||||||
|
config.storage.shuffle = db_config.shuffle;
|
||||||
|
config.text.add_text = db_config.add_text;
|
||||||
|
config.text.fontfile = db_config.fontfile;
|
||||||
|
config.text.text_from_filename = db_config.text_from_filename;
|
||||||
|
config.text.style = db_config.style;
|
||||||
|
config.text.regex = db_config.regex;
|
||||||
|
config.task.enable = db_config.task_enable;
|
||||||
|
config.task.path = PathBuf::from(db_config.task_path);
|
||||||
|
config.output.mode = string_to_output_mode(db_config.output_mode);
|
||||||
|
config.output.output_param = db_config.output_param;
|
||||||
|
|
||||||
|
Ok(web::Json("Update success"))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// #### Text Presets
|
/// #### Text Presets
|
||||||
@ -727,6 +801,13 @@ pub async fn process_control(
|
|||||||
let manager = controllers.lock().unwrap().get(*id).unwrap();
|
let manager = controllers.lock().unwrap().get(*id).unwrap();
|
||||||
|
|
||||||
match proc.into_inner().command {
|
match proc.into_inner().command {
|
||||||
|
ProcessCtl::Status => {
|
||||||
|
if manager.is_alive.load(Ordering::SeqCst) {
|
||||||
|
return Ok(web::Json("active"));
|
||||||
|
} else {
|
||||||
|
return Ok(web::Json("not running"));
|
||||||
|
}
|
||||||
|
}
|
||||||
ProcessCtl::Start => {
|
ProcessCtl::Start => {
|
||||||
manager.async_start().await;
|
manager.async_start().await;
|
||||||
}
|
}
|
||||||
@ -740,7 +821,7 @@ pub async fn process_control(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(web::Json("no implemented"))
|
Ok(web::Json("Success"))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// #### ffplayout Playlist Operations
|
/// #### ffplayout Playlist Operations
|
||||||
|
@ -147,6 +147,67 @@ pub async fn select_configuration(
|
|||||||
sqlx::query_as(query).bind(channel).fetch_one(conn).await
|
sqlx::query_as(query).bind(channel).fetch_one(conn).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn update_configuration(
|
||||||
|
conn: &Pool<Sqlite>,
|
||||||
|
config: Configuration,
|
||||||
|
) -> Result<SqliteQueryResult, sqlx::Error> {
|
||||||
|
let query = "UPDATE configurations SET stop_threshold = $2, subject = $3, smtp_server = $4, sender_addr = $5, sender_pass = $6, recipient = $7, starttls = $8, mail_level = $9, interval = $10, ffmpeg_level = $11, ingest_level = $12, detect_silence = $13 , ignore_lines = $14, processing_mode = $15, audio_only = $16, copy_audio = $17, copy_video = $18, width = $19, height = $20, aspect = $21, add_logo = $22, logo = $23, logo_scale = $24, logo_opacity = $25, logo_position = $26, audio_tracks = $27, audio_track_index = $28, audio_channels = $29, volume = $30, decoder_filter = $31, ingest_enable = $32, ingest_param = $33, ingest_filter = $34, playlist_path = $35, day_start = $36, length = $37, infinit = $38, storage_path = $39, filler = $40, extensions = $41, shuffle = $42, add_text = $43, text_from_filename = $44, fontfile = $45, regex = $46, task_enable = $47, task_path = $48, output_mode = $49, output_param = $50 WHERE id = $1";
|
||||||
|
|
||||||
|
sqlx::query(query)
|
||||||
|
.bind(config.id)
|
||||||
|
.bind(config.stop_threshold)
|
||||||
|
.bind(config.subject)
|
||||||
|
.bind(config.smtp_server)
|
||||||
|
.bind(config.sender_addr)
|
||||||
|
.bind(config.sender_pass)
|
||||||
|
.bind(config.recipient)
|
||||||
|
.bind(config.starttls)
|
||||||
|
.bind(config.mail_level)
|
||||||
|
.bind(config.interval)
|
||||||
|
.bind(config.ffmpeg_level)
|
||||||
|
.bind(config.ingest_level)
|
||||||
|
.bind(config.detect_silence)
|
||||||
|
.bind(config.ignore_lines)
|
||||||
|
.bind(config.processing_mode)
|
||||||
|
.bind(config.audio_only)
|
||||||
|
.bind(config.copy_audio)
|
||||||
|
.bind(config.copy_video)
|
||||||
|
.bind(config.width)
|
||||||
|
.bind(config.height)
|
||||||
|
.bind(config.aspect)
|
||||||
|
.bind(config.add_logo)
|
||||||
|
.bind(config.logo)
|
||||||
|
.bind(config.logo_scale)
|
||||||
|
.bind(config.logo_opacity)
|
||||||
|
.bind(config.logo_position)
|
||||||
|
.bind(config.audio_tracks)
|
||||||
|
.bind(config.audio_track_index)
|
||||||
|
.bind(config.audio_channels)
|
||||||
|
.bind(config.volume)
|
||||||
|
.bind(config.decoder_filter)
|
||||||
|
.bind(config.ingest_enable)
|
||||||
|
.bind(config.ingest_param)
|
||||||
|
.bind(config.ingest_filter)
|
||||||
|
.bind(config.playlist_path)
|
||||||
|
.bind(config.day_start)
|
||||||
|
.bind(config.length)
|
||||||
|
.bind(config.infinit)
|
||||||
|
.bind(config.storage_path)
|
||||||
|
.bind(config.filler)
|
||||||
|
.bind(config.extensions)
|
||||||
|
.bind(config.shuffle)
|
||||||
|
.bind(config.add_text)
|
||||||
|
.bind(config.text_from_filename)
|
||||||
|
.bind(config.fontfile)
|
||||||
|
.bind(config.regex)
|
||||||
|
.bind(config.task_enable)
|
||||||
|
.bind(config.task_path)
|
||||||
|
.bind(config.output_mode)
|
||||||
|
.bind(config.output_param)
|
||||||
|
.execute(conn)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn select_advanced_configuration(
|
pub async fn select_advanced_configuration(
|
||||||
conn: &Pool<Sqlite>,
|
conn: &Pool<Sqlite>,
|
||||||
channel: i32,
|
channel: i32,
|
||||||
|
@ -4,6 +4,8 @@ use serde::{
|
|||||||
Deserialize, Serialize,
|
Deserialize, Serialize,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use crate::utils::config::PlayoutConfig;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, Serialize, sqlx::FromRow)]
|
#[derive(Debug, Deserialize, Serialize, sqlx::FromRow)]
|
||||||
pub struct User {
|
pub struct User {
|
||||||
#[sqlx(default)]
|
#[sqlx(default)]
|
||||||
@ -184,7 +186,6 @@ pub struct Configuration {
|
|||||||
|
|
||||||
pub storage_help: String,
|
pub storage_help: String,
|
||||||
pub storage_path: String,
|
pub storage_path: String,
|
||||||
|
|
||||||
#[serde(alias = "filler_clip")]
|
#[serde(alias = "filler_clip")]
|
||||||
pub filler: String,
|
pub filler: String,
|
||||||
pub extensions: String,
|
pub extensions: String,
|
||||||
@ -206,6 +207,76 @@ pub struct Configuration {
|
|||||||
pub output_param: String,
|
pub output_param: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Configuration {
|
||||||
|
pub fn from(id: i32, channel_id: i32, config: PlayoutConfig) -> Self {
|
||||||
|
Self {
|
||||||
|
id,
|
||||||
|
channel_id,
|
||||||
|
general_help: config.general.help_text,
|
||||||
|
stop_threshold: config.general.stop_threshold,
|
||||||
|
mail_help: config.mail.help_text,
|
||||||
|
subject: config.mail.subject,
|
||||||
|
smtp_server: config.mail.smtp_server,
|
||||||
|
starttls: config.mail.starttls,
|
||||||
|
sender_addr: config.mail.sender_addr,
|
||||||
|
sender_pass: config.mail.sender_pass,
|
||||||
|
recipient: config.mail.recipient,
|
||||||
|
mail_level: config.mail.mail_level.to_string(),
|
||||||
|
interval: config.mail.interval as i64,
|
||||||
|
logging_help: config.logging.help_text,
|
||||||
|
ffmpeg_level: config.logging.ffmpeg_level,
|
||||||
|
ingest_level: config.logging.ingest_level,
|
||||||
|
detect_silence: config.logging.detect_silence,
|
||||||
|
ignore_lines: config.logging.ignore_lines.join(";"),
|
||||||
|
processing_help: config.processing.help_text,
|
||||||
|
processing_mode: config.processing.mode.to_string(),
|
||||||
|
audio_only: config.processing.audio_only,
|
||||||
|
audio_track_index: config.processing.audio_track_index,
|
||||||
|
copy_audio: config.processing.copy_audio,
|
||||||
|
copy_video: config.processing.copy_video,
|
||||||
|
width: config.processing.width,
|
||||||
|
height: config.processing.height,
|
||||||
|
aspect: config.processing.aspect,
|
||||||
|
fps: config.processing.fps,
|
||||||
|
add_logo: config.processing.add_logo,
|
||||||
|
logo: config.processing.logo,
|
||||||
|
logo_scale: config.processing.logo_scale,
|
||||||
|
logo_opacity: config.processing.logo_opacity,
|
||||||
|
logo_position: config.processing.logo_position,
|
||||||
|
audio_tracks: config.processing.audio_tracks,
|
||||||
|
audio_channels: config.processing.audio_channels,
|
||||||
|
volume: config.processing.volume,
|
||||||
|
decoder_filter: config.processing.custom_filter,
|
||||||
|
ingest_help: config.ingest.help_text,
|
||||||
|
ingest_enable: config.ingest.enable,
|
||||||
|
ingest_param: config.ingest.input_param,
|
||||||
|
ingest_filter: config.ingest.custom_filter,
|
||||||
|
playlist_help: config.playlist.help_text,
|
||||||
|
playlist_path: config.playlist.path.to_string_lossy().to_string(),
|
||||||
|
day_start: config.playlist.day_start,
|
||||||
|
length: config.playlist.length,
|
||||||
|
infinit: config.playlist.infinit,
|
||||||
|
storage_help: config.storage.help_text,
|
||||||
|
storage_path: config.storage.path.to_string_lossy().to_string(),
|
||||||
|
filler: config.storage.filler.to_string_lossy().to_string(),
|
||||||
|
extensions: config.storage.extensions.join(";"),
|
||||||
|
shuffle: config.storage.shuffle,
|
||||||
|
text_help: config.text.help_text,
|
||||||
|
add_text: config.text.add_text,
|
||||||
|
fontfile: config.text.fontfile,
|
||||||
|
text_from_filename: config.text.text_from_filename,
|
||||||
|
style: config.text.style,
|
||||||
|
regex: config.text.regex,
|
||||||
|
task_help: config.task.help_text,
|
||||||
|
task_enable: config.task.enable,
|
||||||
|
task_path: config.task.path.to_string_lossy().to_string(),
|
||||||
|
output_help: config.output.help_text,
|
||||||
|
output_mode: config.output.mode.to_string(),
|
||||||
|
output_param: config.output.output_param,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn default_track_index() -> i32 {
|
fn default_track_index() -> i32 {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,6 @@ async fn main() -> std::io::Result<()> {
|
|||||||
let thread_count = thread_counter();
|
let thread_count = thread_counter();
|
||||||
|
|
||||||
info!("Running ffplayout API, listen on http://{conn}");
|
info!("Running ffplayout API, listen on http://{conn}");
|
||||||
debug!("Use {thread_count} threads for the webserver");
|
|
||||||
|
|
||||||
// no 'allow origin' here, give it to the reverse proxy
|
// no 'allow origin' here, give it to the reverse proxy
|
||||||
HttpServer::new(move || {
|
HttpServer::new(move || {
|
||||||
|
@ -45,6 +45,7 @@ pub const FFMPEG_UNRECOVERABLE_ERRORS: [&str; 5] = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
|
#[derive(Debug, Clone, Eq, PartialEq, Deserialize, Serialize)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
pub enum OutputMode {
|
pub enum OutputMode {
|
||||||
Desktop,
|
Desktop,
|
||||||
HLS,
|
HLS,
|
||||||
@ -83,6 +84,17 @@ impl FromStr for OutputMode {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for OutputMode {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
match *self {
|
||||||
|
OutputMode::Desktop => write!(f, "desktop"),
|
||||||
|
OutputMode::HLS => write!(f, "hls"),
|
||||||
|
OutputMode::Null => write!(f, "null"),
|
||||||
|
OutputMode::Stream => write!(f, "stream"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Default, Clone, Serialize, Deserialize, Eq, PartialEq)]
|
#[derive(Debug, Default, Clone, Serialize, Deserialize, Eq, PartialEq)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
pub enum ProcessMode {
|
pub enum ProcessMode {
|
||||||
@ -139,7 +151,7 @@ pub struct Source {
|
|||||||
/// This we init ones, when ffplayout is starting and use them globally in the hole program.
|
/// This we init ones, when ffplayout is starting and use them globally in the hole program.
|
||||||
#[derive(Debug, Default, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Default, Clone, Deserialize, Serialize)]
|
||||||
pub struct PlayoutConfig {
|
pub struct PlayoutConfig {
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub advanced: AdvancedConfig,
|
pub advanced: AdvancedConfig,
|
||||||
pub general: General,
|
pub general: General,
|
||||||
pub mail: Mail,
|
pub mail: Mail,
|
||||||
@ -156,28 +168,31 @@ pub struct PlayoutConfig {
|
|||||||
#[derive(Debug, Default, Clone, Deserialize, Serialize)]
|
#[derive(Debug, Default, Clone, Deserialize, Serialize)]
|
||||||
pub struct General {
|
pub struct General {
|
||||||
pub help_text: String,
|
pub help_text: String,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
|
pub id: i32,
|
||||||
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub channel_id: i32,
|
pub channel_id: i32,
|
||||||
pub stop_threshold: f64,
|
pub stop_threshold: f64,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub generate: Option<Vec<String>>,
|
pub generate: Option<Vec<String>>,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub ffmpeg_filters: Vec<String>,
|
pub ffmpeg_filters: Vec<String>,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub ffmpeg_libs: Vec<String>,
|
pub ffmpeg_libs: Vec<String>,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub template: Option<Template>,
|
pub template: Option<Template>,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub skip_validation: bool,
|
pub skip_validation: bool,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub validate: bool,
|
pub validate: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl General {
|
impl General {
|
||||||
fn new(channel_id: i32, config: &Configuration) -> Self {
|
fn new(config: &Configuration) -> Self {
|
||||||
Self {
|
Self {
|
||||||
help_text: config.general_help.clone(),
|
help_text: config.general_help.clone(),
|
||||||
channel_id,
|
id: config.id,
|
||||||
|
channel_id: config.channel_id,
|
||||||
stop_threshold: config.stop_threshold,
|
stop_threshold: config.stop_threshold,
|
||||||
generate: None,
|
generate: None,
|
||||||
ffmpeg_filters: vec![],
|
ffmpeg_filters: vec![],
|
||||||
@ -281,7 +296,7 @@ pub struct Processing {
|
|||||||
pub audio_channels: u8,
|
pub audio_channels: u8,
|
||||||
pub volume: f64,
|
pub volume: f64,
|
||||||
pub custom_filter: String,
|
pub custom_filter: String,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub cmd: Option<Vec<String>>,
|
pub cmd: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,9 +331,9 @@ impl Processing {
|
|||||||
pub struct Ingest {
|
pub struct Ingest {
|
||||||
pub help_text: String,
|
pub help_text: String,
|
||||||
pub enable: bool,
|
pub enable: bool,
|
||||||
input_param: String,
|
pub input_param: String,
|
||||||
pub custom_filter: String,
|
pub custom_filter: String,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub input_cmd: Option<Vec<String>>,
|
pub input_cmd: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -339,10 +354,10 @@ pub struct Playlist {
|
|||||||
pub help_text: String,
|
pub help_text: String,
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
pub day_start: String,
|
pub day_start: String,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub start_sec: Option<f64>,
|
pub start_sec: Option<f64>,
|
||||||
pub length: String,
|
pub length: String,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub length_sec: Option<f64>,
|
pub length_sec: Option<f64>,
|
||||||
pub infinit: bool,
|
pub infinit: bool,
|
||||||
}
|
}
|
||||||
@ -365,7 +380,7 @@ impl Playlist {
|
|||||||
pub struct Storage {
|
pub struct Storage {
|
||||||
pub help_text: String,
|
pub help_text: String,
|
||||||
pub path: PathBuf,
|
pub path: PathBuf,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub paths: Vec<PathBuf>,
|
pub paths: Vec<PathBuf>,
|
||||||
pub filler: PathBuf,
|
pub filler: PathBuf,
|
||||||
pub extensions: Vec<String>,
|
pub extensions: Vec<String>,
|
||||||
@ -393,11 +408,11 @@ impl Storage {
|
|||||||
pub struct Text {
|
pub struct Text {
|
||||||
pub help_text: String,
|
pub help_text: String,
|
||||||
pub add_text: bool,
|
pub add_text: bool,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub node_pos: Option<usize>,
|
pub node_pos: Option<usize>,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub zmq_stream_socket: Option<String>,
|
pub zmq_stream_socket: Option<String>,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub zmq_server_socket: Option<String>,
|
pub zmq_server_socket: Option<String>,
|
||||||
pub fontfile: String,
|
pub fontfile: String,
|
||||||
pub text_from_filename: bool,
|
pub text_from_filename: bool,
|
||||||
@ -443,11 +458,11 @@ pub struct Output {
|
|||||||
pub help_text: String,
|
pub help_text: String,
|
||||||
pub mode: OutputMode,
|
pub mode: OutputMode,
|
||||||
pub output_param: String,
|
pub output_param: String,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub output_count: usize,
|
pub output_count: usize,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub output_filter: Option<String>,
|
pub output_filter: Option<String>,
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing, skip_deserializing)]
|
||||||
pub output_cmd: Option<Vec<String>>,
|
pub output_cmd: Option<Vec<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -474,6 +489,24 @@ pub fn string_to_log_level(l: String) -> Level {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn string_to_processing_mode(l: String) -> ProcessMode {
|
||||||
|
match l.to_lowercase().as_str() {
|
||||||
|
"playlist" => ProcessMode::Playlist,
|
||||||
|
"folder" => ProcessMode::Folder,
|
||||||
|
_ => ProcessMode::Playlist,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn string_to_output_mode(l: String) -> OutputMode {
|
||||||
|
match l.to_lowercase().as_str() {
|
||||||
|
"desktop" => OutputMode::Desktop,
|
||||||
|
"hls" => OutputMode::HLS,
|
||||||
|
"null" => OutputMode::Null,
|
||||||
|
"stream" => OutputMode::Stream,
|
||||||
|
_ => OutputMode::HLS,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn default_track_index() -> i32 {
|
fn default_track_index() -> i32 {
|
||||||
-1
|
-1
|
||||||
}
|
}
|
||||||
@ -496,7 +529,7 @@ impl PlayoutConfig {
|
|||||||
.expect("Can't read advanced config");
|
.expect("Can't read advanced config");
|
||||||
|
|
||||||
let advanced = AdvancedConfig::new(adv_config);
|
let advanced = AdvancedConfig::new(adv_config);
|
||||||
let general = General::new(channel, &config);
|
let general = General::new(&config);
|
||||||
let mail = Mail::new(&config);
|
let mail = Mail::new(&config);
|
||||||
let logging = Logging::new(&config);
|
let logging = Logging::new(&config);
|
||||||
let mut processing = Processing::new(&config);
|
let mut processing = Processing::new(&config);
|
||||||
|
@ -32,6 +32,7 @@ struct MediaParams {
|
|||||||
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
|
#[derive(Debug, Serialize, Deserialize, Clone, Eq, PartialEq)]
|
||||||
#[serde(rename_all = "snake_case")]
|
#[serde(rename_all = "snake_case")]
|
||||||
pub enum ProcessCtl {
|
pub enum ProcessCtl {
|
||||||
|
Status,
|
||||||
Start,
|
Start,
|
||||||
Stop,
|
Stop,
|
||||||
Restart,
|
Restart,
|
||||||
@ -42,6 +43,7 @@ impl FromStr for ProcessCtl {
|
|||||||
|
|
||||||
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
fn from_str(input: &str) -> Result<Self, Self::Err> {
|
||||||
match input.to_lowercase().as_str() {
|
match input.to_lowercase().as_str() {
|
||||||
|
"status" => Ok(Self::Status),
|
||||||
"start" => Ok(Self::Start),
|
"start" => Ok(Self::Start),
|
||||||
"stop" => Ok(Self::Stop),
|
"stop" => Ok(Self::Stop),
|
||||||
"restart" => Ok(Self::Restart),
|
"restart" => Ok(Self::Restart),
|
||||||
@ -53,6 +55,7 @@ impl FromStr for ProcessCtl {
|
|||||||
impl fmt::Display for ProcessCtl {
|
impl fmt::Display for ProcessCtl {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
match *self {
|
match *self {
|
||||||
|
Self::Status => write!(f, "status"),
|
||||||
Self::Start => write!(f, "start"),
|
Self::Start => write!(f, "start"),
|
||||||
Self::Stop => write!(f, "stop"),
|
Self::Stop => write!(f, "stop"),
|
||||||
Self::Restart => write!(f, "restart"),
|
Self::Restart => write!(f, "restart"),
|
||||||
|
@ -405,7 +405,6 @@ pub fn init_logging(mail_queues: Arc<Mutex<Vec<Arc<Mutex<MailQueue>>>>>) -> io::
|
|||||||
builder
|
builder
|
||||||
.default(log_level)
|
.default(log_level)
|
||||||
.module("actix_files", LevelFilter::Error)
|
.module("actix_files", LevelFilter::Error)
|
||||||
.module("actix_web", LevelFilter::Error)
|
|
||||||
.module("hyper", LevelFilter::Error)
|
.module("hyper", LevelFilter::Error)
|
||||||
.module("libc", LevelFilter::Error)
|
.module("libc", LevelFilter::Error)
|
||||||
.module("neli", LevelFilter::Error)
|
.module("neli", LevelFilter::Error)
|
||||||
|
@ -63,10 +63,7 @@ CREATE TABLE configurations (
|
|||||||
starttls INTEGER NOT NULL DEFAULT 0,
|
starttls INTEGER NOT NULL DEFAULT 0,
|
||||||
mail_level TEXT NOT NULL DEFAULT "ERROR",
|
mail_level TEXT NOT NULL DEFAULT "ERROR",
|
||||||
interval INTEGER NOT NULL DEFAULT 120,
|
interval INTEGER NOT NULL DEFAULT 120,
|
||||||
logging_help TEXT NOT NULL DEFAULT "If 'log_to_file' is true, log to file, when is false log to console. \n'backup_count' says how long log files will be saved in days.\n'local_time' to false will set log timestamps to UTC. Path to /var/log/ only if you run this program as daemon.\n'level' can be DEBUG, INFO, WARNING, ERROR.\n'ffmpeg_level/ingest_level' can be INFO, WARNING, ERROR.\n'detect_silence' logs an error message if the audio line is silent for 15 seconds during the validation process.\n'ignore_lines' makes logging to ignore strings that contains matched lines, in frontend is a semicolon separated list.",
|
logging_help TEXT NOT NULL DEFAULT "If 'log_to_file' is true, log to file, when is false log to console. \n'local_time' to false will set log timestamps to UTC. Path to /var/log/ only if you run this program as daemon.\n'level' can be DEBUG, INFO, WARNING, ERROR.\n'ffmpeg_level/ingest_level' can be INFO, WARNING, ERROR.\n'detect_silence' logs an error message if the audio line is silent for 15 seconds during the validation process.\n'ignore_lines' makes logging to ignore strings that contains matched lines, in frontend is a semicolon separated list.",
|
||||||
log_to_file INTEGER NOT NULL DEFAULT 1,
|
|
||||||
backup_count INTEGER NOT NULL DEFAULT 7,
|
|
||||||
local_time INTEGER NOT NULL DEFAULT 1,
|
|
||||||
ffmpeg_level TEXT NOT NULL DEFAULT "ERROR",
|
ffmpeg_level TEXT NOT NULL DEFAULT "ERROR",
|
||||||
ingest_level TEXT NOT NULL DEFAULT "ERROR",
|
ingest_level TEXT NOT NULL DEFAULT "ERROR",
|
||||||
detect_silence INTEGER NOT NULL DEFAULT 1,
|
detect_silence INTEGER NOT NULL DEFAULT 1,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user