add controls, next, back, reset and get media info

This commit is contained in:
jb-alvarado 2022-06-19 22:03:17 +02:00
parent 03dc21c6a3
commit 4834b47d74
5 changed files with 141 additions and 28 deletions

View File

@ -1,3 +1,5 @@
use std::collections::HashMap;
use reqwest::{
header::{HeaderMap, AUTHORIZATION, CONTENT_TYPE},
Client, Response,
@ -5,9 +7,7 @@ use reqwest::{
use serde::{Deserialize, Serialize};
use simplelog::*;
use crate::api::{
errors::ServiceError, handles::db_get_settings, models::TextPreset, utils::read_playout_config,
};
use crate::api::{errors::ServiceError, handles::db_get_settings, utils::read_playout_config};
use crate::utils::PlayoutConfig;
#[derive(Debug, Deserialize, Serialize, Clone)]
@ -21,7 +21,17 @@ struct RpcObj<T> {
#[derive(Debug, Deserialize, Serialize, Clone)]
struct TextParams {
control: String,
message: TextPreset,
message: HashMap<String, String>,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
struct ControlParams {
control: String,
}
#[derive(Debug, Deserialize, Serialize, Clone)]
struct MediaParams {
media: String,
}
impl<T> RpcObj<T> {
@ -58,23 +68,18 @@ async fn playout_config(channel_id: &i64) -> Result<PlayoutConfig, ServiceError>
))
}
pub async fn send_message(id: i64, message: TextPreset) -> Result<Response, ServiceError> {
async fn post_request<T>(id: i64, obj: RpcObj<T>) -> Result<Response, ServiceError>
where
T: Serialize,
{
let config = playout_config(&id).await?;
let url = format!("http://{}", config.rpc_server.address);
let client = Client::new();
let json_obj = RpcObj::new(
id,
"player".into(),
TextParams {
control: "text".into(),
message,
},
);
match client
.post(&url)
.headers(create_header(&config.rpc_server.authorization))
.json(&json_obj)
.json(&obj)
.send()
.await
{
@ -85,3 +90,31 @@ pub async fn send_message(id: i64, message: TextPreset) -> Result<Response, Serv
}
}
}
pub async fn send_message(
id: i64,
message: HashMap<String, String>,
) -> Result<Response, ServiceError> {
let json_obj = RpcObj::new(
id,
"player".into(),
TextParams {
control: "text".into(),
message,
},
);
post_request(id, json_obj).await
}
pub async fn control_state(id: i64, command: String) -> Result<Response, ServiceError> {
let json_obj = RpcObj::new(id, "player".into(), ControlParams { control: command });
post_request(id, json_obj).await
}
pub async fn media_info(id: i64, command: String) -> Result<Response, ServiceError> {
let json_obj = RpcObj::new(id, "player".into(), MediaParams { media: command });
post_request(id, json_obj).await
}

View File

@ -40,12 +40,12 @@ async fn create_schema() -> Result<SqliteQueryResult, sqlx::Error> {
text TEXT NOT NULL,
x TEXT NOT NULL,
y TEXT NOT NULL,
fontsize INTEGER NOT NULL DEFAULT 24,
line_spacing INTEGER NOT NULL DEFAULT 4,
fontsize TEXT NOT NULL,
line_spacing TEXT NOT NULL,
fontcolor TEXT NOT NULL,
box INTEGER NOT NULL DEFAULT 1,
box TEXT NOT NULL,
boxcolor TEXT NOT NULL,
boxborderw INTEGER NOT NULL DEFAULT 4,
boxborderw TEXT NOT NULL,
alpha TEXT NOT NULL,
UNIQUE(name)
);

View File

@ -46,12 +46,12 @@ pub struct TextPreset {
pub text: String,
pub x: String,
pub y: String,
pub fontsize: i64,
pub line_spacing: i64,
pub fontsize: String,
pub line_spacing: String,
pub fontcolor: String,
pub r#box: bool,
pub r#box: String,
pub boxcolor: String,
pub boxborderw: i64,
pub boxborderw: String,
pub alpha: String,
}

View File

@ -1,3 +1,5 @@
use std::collections::HashMap;
use actix_web::{get, http::StatusCode, patch, post, put, web, Responder};
use actix_web_grants::{permissions::AuthDetails, proc_macro::has_any_role};
use argon2::{
@ -9,7 +11,7 @@ use simplelog::*;
use crate::api::{
auth::{create_jwt, Claims},
control::send_message,
control::{control_state, media_info, send_message},
errors::ServiceError,
handles::{
db_add_preset, db_add_user, db_get_presets, db_get_settings, db_login, db_role,
@ -265,14 +267,85 @@ pub async fn login(credentials: web::Json<User>) -> impl Responder {
/// - send text the the engine, for overlaying it (as lower third etc.)
/// ----------------------------------------------------------------------------
#[post("/control/text/{id}")]
/// curl -X POST http://localhost:8080/api/control/1/text/ \
/// --header 'Content-Type: application/json' --header 'Authorization: <TOKEN>' \
/// --data '{"text": "Hello from ffplayout", "x": "(w-text_w)/2", "y": "(h-text_h)/2", \
/// "fontsize": "24", "line_spacing": "4", "fontcolor": "#ffffff", "box": "1", \
/// "boxcolor": "#000000", "boxborderw": "4", "alpha": "1.0"}'
#[post("/control/{id}/text/")]
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
pub async fn send_text_message(
id: web::Path<i64>,
data: web::Json<TextPreset>,
data: web::Json<HashMap<String, String>>,
) -> Result<impl Responder, ServiceError> {
match send_message(*id, data.into_inner()).await {
Ok(res) => return Ok(res.text().await.unwrap_or_else(|_| "Success".into())),
Err(e) => Err(e),
}
}
/// curl -X POST http://localhost:8080/api/control/1/playout/next/
/// --header 'Content-Type: application/json' --header 'Authorization: <TOKEN>'
#[post("/control/{id}/playout/next/")]
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
pub async fn jump_to_next(id: web::Path<i64>) -> Result<impl Responder, ServiceError> {
match control_state(*id, "next".into()).await {
Ok(res) => return Ok(res.text().await.unwrap_or_else(|_| "Success".into())),
Err(e) => Err(e),
}
}
/// curl -X POST http://localhost:8080/api/control/1/playout/back/
/// --header 'Content-Type: application/json' --header 'Authorization: <TOKEN>'
#[post("/control/{id}/playout/back/")]
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
pub async fn jump_to_last(id: web::Path<i64>) -> Result<impl Responder, ServiceError> {
match control_state(*id, "back".into()).await {
Ok(res) => return Ok(res.text().await.unwrap_or_else(|_| "Success".into())),
Err(e) => Err(e),
}
}
/// curl -X POST http://localhost:8080/api/control/1/playout/reset/
/// --header 'Content-Type: application/json' --header 'Authorization: <TOKEN>'
#[post("/control/{id}/playout/reset/")]
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
pub async fn reset_playout(id: web::Path<i64>) -> Result<impl Responder, ServiceError> {
match control_state(*id, "reset".into()).await {
Ok(res) => return Ok(res.text().await.unwrap_or_else(|_| "Success".into())),
Err(e) => Err(e),
}
}
/// curl -X GET http://localhost:8080/api/control/1/media/current/
/// --header 'Content-Type: application/json' --header 'Authorization: <TOKEN>'
#[get("/control/{id}/media/current/")]
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
pub async fn media_current(id: web::Path<i64>) -> Result<impl Responder, ServiceError> {
match media_info(*id, "current".into()).await {
Ok(res) => return Ok(res.text().await.unwrap_or_else(|_| "Success".into())),
Err(e) => Err(e),
}
}
/// curl -X GET http://localhost:8080/api/control/1/media/next/
/// --header 'Content-Type: application/json' --header 'Authorization: <TOKEN>'
#[get("/control/{id}/media/next/")]
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
pub async fn media_next(id: web::Path<i64>) -> Result<impl Responder, ServiceError> {
match media_info(*id, "next".into()).await {
Ok(res) => return Ok(res.text().await.unwrap_or_else(|_| "Success".into())),
Err(e) => Err(e),
}
}
/// curl -X GET http://localhost:8080/api/control/1/media/last/
/// --header 'Content-Type: application/json' --header 'Authorization: <TOKEN>'
#[get("/control/{id}/media/last/")]
#[has_any_role("Role::Admin", "Role::User", type = "Role")]
pub async fn media_last(id: web::Path<i64>) -> Result<impl Responder, ServiceError> {
match media_info(*id, "last".into()).await {
Ok(res) => return Ok(res.text().await.unwrap_or_else(|_| "Success".into())),
Err(e) => Err(e),
}
}

View File

@ -14,8 +14,9 @@ use ffplayout_engine::{
auth,
models::LoginUser,
routes::{
add_preset, add_user, get_playout_config, get_presets, get_settings, login,
patch_settings, send_text_message, update_playout_config, update_preset, update_user,
add_preset, add_user, get_playout_config, get_presets, get_settings, jump_to_last,
jump_to_next, login, media_current, media_last, media_next, patch_settings,
reset_playout, send_text_message, update_playout_config, update_preset, update_user,
},
utils::{db_path, init_config, run_args, Role},
},
@ -81,7 +82,13 @@ async fn main() -> std::io::Result<()> {
.service(get_settings)
.service(patch_settings)
.service(update_user)
.service(send_text_message),
.service(send_text_message)
.service(jump_to_next)
.service(jump_to_last)
.service(reset_playout)
.service(media_current)
.service(media_next)
.service(media_last),
)
})
.bind((addr, port))?