feat: add config file loading
This commit is contained in:
parent
381c086eba
commit
67be4dc233
7 changed files with 369 additions and 32 deletions
152
Cargo.lock
generated
152
Cargo.lock
generated
|
|
@ -86,6 +86,15 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "atomic"
|
||||||
|
version = "0.6.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a89cbf775b137e9b968e67227ef7f775587cde3fd31b0d8599dbd0f598a48340"
|
||||||
|
dependencies = [
|
||||||
|
"bytemuck",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "atomic-waker"
|
name = "atomic-waker"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
|
|
@ -116,6 +125,12 @@ version = "3.19.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bytemuck"
|
||||||
|
version = "1.24.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1fbdf580320f38b612e485521afda1ee26d10cc9884efaaa750d383e13e3c5f4"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bytes"
|
name = "bytes"
|
||||||
version = "1.10.1"
|
version = "1.10.1"
|
||||||
|
|
@ -282,6 +297,20 @@ version = "2.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "figment"
|
||||||
|
version = "0.10.19"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8cb01cd46b0cf372153850f4c6c272d9cbea2da513e07538405148f95bd789f3"
|
||||||
|
dependencies = [
|
||||||
|
"atomic",
|
||||||
|
"pear",
|
||||||
|
"serde",
|
||||||
|
"toml",
|
||||||
|
"uncased",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "find-msvc-tools"
|
name = "find-msvc-tools"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
|
|
@ -682,6 +711,12 @@ dependencies = [
|
||||||
"hashbrown",
|
"hashbrown",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inlinable_string"
|
||||||
|
version = "0.1.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c8fae54786f62fb2918dcfae3d568594e50eb9b5c25bf04371af6fe7516452fb"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ipnet"
|
name = "ipnet"
|
||||||
version = "2.11.0"
|
version = "2.11.0"
|
||||||
|
|
@ -891,6 +926,29 @@ dependencies = [
|
||||||
"windows-link 0.2.1",
|
"windows-link 0.2.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pear"
|
||||||
|
version = "0.2.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bdeeaa00ce488657faba8ebf44ab9361f9365a97bd39ffb8a60663f57ff4b467"
|
||||||
|
dependencies = [
|
||||||
|
"inlinable_string",
|
||||||
|
"pear_codegen",
|
||||||
|
"yansi",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pear_codegen"
|
||||||
|
version = "0.2.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4bab5b985dc082b345f812b7df84e1bef27e7207b39e448439ba8bd69c93f147"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"proc-macro2-diagnostics",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.3.2"
|
version = "2.3.2"
|
||||||
|
|
@ -942,6 +1000,19 @@ dependencies = [
|
||||||
"unicode-ident",
|
"unicode-ident",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "proc-macro2-diagnostics"
|
||||||
|
version = "0.10.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
"version_check",
|
||||||
|
"yansi",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "quote"
|
name = "quote"
|
||||||
version = "1.0.41"
|
version = "1.0.41"
|
||||||
|
|
@ -1191,6 +1262,15 @@ dependencies = [
|
||||||
"serde_core",
|
"serde_core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_spanned"
|
||||||
|
version = "0.6.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bf41e0cfaf7226dca15e8197172c295a782857fcb97fad1808a166870dee75a3"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "serde_urlencoded"
|
name = "serde_urlencoded"
|
||||||
version = "0.7.1"
|
version = "0.7.1"
|
||||||
|
|
@ -1400,6 +1480,47 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml"
|
||||||
|
version = "0.8.23"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "dc1beb996b9d83529a9e75c17a1686767d148d70663143c7854d8b4a09ced362"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_edit",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_datetime"
|
||||||
|
version = "0.6.11"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "22cddaf88f4fbc13c51aebbf5f8eceb5c7c5a9da2ac40a13519eb5b0a0e8f11c"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_edit"
|
||||||
|
version = "0.22.27"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a"
|
||||||
|
dependencies = [
|
||||||
|
"indexmap",
|
||||||
|
"serde",
|
||||||
|
"serde_spanned",
|
||||||
|
"toml_datetime",
|
||||||
|
"toml_write",
|
||||||
|
"winnow",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "toml_write"
|
||||||
|
version = "0.1.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5d99f8c9a7727884afe522e9bd5edbfc91a3312b36a77b5fb8926e4c31a41801"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tower"
|
name = "tower"
|
||||||
version = "0.5.2"
|
version = "0.5.2"
|
||||||
|
|
@ -1477,6 +1598,7 @@ dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
|
"figment",
|
||||||
"rand",
|
"rand",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
|
|
@ -1485,6 +1607,15 @@ dependencies = [
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "uncased"
|
||||||
|
version = "0.9.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697"
|
||||||
|
dependencies = [
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-ident"
|
name = "unicode-ident"
|
||||||
version = "1.0.19"
|
version = "1.0.19"
|
||||||
|
|
@ -1538,6 +1669,12 @@ version = "0.2.15"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "version_check"
|
||||||
|
version = "0.9.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "want"
|
name = "want"
|
||||||
version = "0.3.1"
|
version = "0.3.1"
|
||||||
|
|
@ -1894,6 +2031,15 @@ version = "0.53.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "winnow"
|
||||||
|
version = "0.7.13"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "21a0236b59786fed61e2a80582dd500fe61f18b5dca67a4a067d0bc9039339cf"
|
||||||
|
dependencies = [
|
||||||
|
"memchr",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wit-bindgen"
|
name = "wit-bindgen"
|
||||||
version = "0.46.0"
|
version = "0.46.0"
|
||||||
|
|
@ -1906,6 +2052,12 @@ version = "0.6.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yansi"
|
||||||
|
version = "1.0.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cfe53a6657fd280eaa890a3bc59152892ffa3e30101319d168b781ed6529b049"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yoke"
|
name = "yoke"
|
||||||
version = "0.8.0"
|
version = "0.8.0"
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ edition = "2024"
|
||||||
anyhow = "1.0.100"
|
anyhow = "1.0.100"
|
||||||
chrono = { version = "0.4.42", features = ["serde"] }
|
chrono = { version = "0.4.42", features = ["serde"] }
|
||||||
clap = { version = "4.5.49", features = ["derive"] }
|
clap = { version = "4.5.49", features = ["derive"] }
|
||||||
|
figment = { version = "0.10.19", features = ["toml", "env"] }
|
||||||
rand = "0.9.2"
|
rand = "0.9.2"
|
||||||
reqwest = { version = "0.12.24", features = ["gzip", "json"] }
|
reqwest = { version = "0.12.24", features = ["gzip", "json"] }
|
||||||
serde = "1.0.228"
|
serde = "1.0.228"
|
||||||
|
|
|
||||||
11
config.toml
Normal file
11
config.toml
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
name = "Foo"
|
||||||
|
|
||||||
|
[[blocks]]
|
||||||
|
schedule_type = { type = "StartAt", time = "8:30 PM", until_tomorrow = true }
|
||||||
|
# VGM Folder
|
||||||
|
content_type = { type = "RandomAlbum", container_id = "574563ff9a41f2c98c234db69157cc87", album_name_as_title = true }
|
||||||
|
|
||||||
|
[blocks.pre_filler]
|
||||||
|
custom_title = "VGM"
|
||||||
|
schedule_type = { type = "All" }
|
||||||
|
content_type = { type = "SmartCollection", name = "VGM - All" }
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
use clap::{Parser, ValueEnum};
|
use clap::{Parser, ValueEnum};
|
||||||
use uuid::Uuid;
|
use figment::{
|
||||||
|
Figment,
|
||||||
|
providers::{Env, Format, Toml},
|
||||||
|
};
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[command(version, about)]
|
#[command(version, about)]
|
||||||
|
|
@ -17,3 +21,48 @@ pub enum PlayoutMode {
|
||||||
Continue,
|
Continue,
|
||||||
Reset,
|
Reset,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
pub struct ScheduleConfig {
|
||||||
|
pub name: String,
|
||||||
|
pub blocks: Vec<ScheduleBlock>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
pub struct ScheduleBlock {
|
||||||
|
pub schedule_type: ScheduleType,
|
||||||
|
pub content_type: ContentType,
|
||||||
|
pub custom_title: Option<String>,
|
||||||
|
pub pre_filler: Option<Box<ScheduleBlock>>,
|
||||||
|
pub post_filler: Option<Box<ScheduleBlock>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
pub enum ScheduleType {
|
||||||
|
All,
|
||||||
|
StartAt { time: String, until_tomorrow: bool },
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, PartialEq, Deserialize)]
|
||||||
|
#[serde(tag = "type")]
|
||||||
|
pub enum ContentType {
|
||||||
|
/// Smart Collection of ErsatzTv
|
||||||
|
SmartCollection { name: String },
|
||||||
|
/// Random album picked from a container Item from Jellyfin
|
||||||
|
RandomAlbum {
|
||||||
|
container_id: String,
|
||||||
|
album_name_as_title: bool,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScheduleConfig {
|
||||||
|
pub fn new(path: Option<String>) -> anyhow::Result<Self> {
|
||||||
|
let config = Figment::new()
|
||||||
|
.merge(Toml::file(path.unwrap_or(String::from("config.toml"))))
|
||||||
|
.merge(Env::prefixed("TV_SDR_"))
|
||||||
|
.extract()?;
|
||||||
|
|
||||||
|
Ok(config)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,14 @@
|
||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use crate::ersatz_tv::models::{ContextModel, ScheduleAllContentDto, SearchQueryDto};
|
use crate::ersatz_tv::models::{ContextModel, Dto, ScheduleAllContentDto};
|
||||||
|
|
||||||
pub mod models;
|
pub mod models;
|
||||||
|
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
_client: reqwest::Client,
|
_client: reqwest::Client,
|
||||||
host: String,
|
host: String,
|
||||||
|
base_endpoint: String,
|
||||||
build_id: String,
|
build_id: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -17,6 +18,7 @@ impl Client {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
_client,
|
_client,
|
||||||
host: host.clone(),
|
host: host.clone(),
|
||||||
|
base_endpoint: format!("{}/api/scripted/playout/build/{}", host, build_id),
|
||||||
build_id: build_id.clone(),
|
build_id: build_id.clone(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -45,14 +47,11 @@ impl Client {
|
||||||
Ok(context)
|
Ok(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn _load_content(&self, content: &SearchQueryDto) -> anyhow::Result<()> {
|
pub async fn post<T: Dto>(&self, endpoint: &str, payload: &T) -> anyhow::Result<()> {
|
||||||
let response = self
|
let response = self
|
||||||
._client
|
._client
|
||||||
.post(format!(
|
.post(format!("{}/{}", self.base_endpoint, endpoint))
|
||||||
"{}/api/scripted/playout/build/{}/add_search",
|
.json(payload)
|
||||||
self.host, self.build_id
|
|
||||||
))
|
|
||||||
.json(content)
|
|
||||||
.send()
|
.send()
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
|
@ -68,17 +67,6 @@ impl Client {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn load_content<T: IntoIterator<Item = SearchQueryDto>>(
|
|
||||||
&self,
|
|
||||||
content: T,
|
|
||||||
) -> anyhow::Result<()> {
|
|
||||||
for item in content {
|
|
||||||
self._load_content(&item).await?;
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn _schedule_content(&self, content: &ScheduleAllContentDto) -> anyhow::Result<()> {
|
async fn _schedule_content(&self, content: &ScheduleAllContentDto) -> anyhow::Result<()> {
|
||||||
let response = self
|
let response = self
|
||||||
._client
|
._client
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,8 @@
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
pub trait Dto: Serialize {}
|
||||||
|
impl<T: Serialize> Dto for T {}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct ContextModel {
|
pub struct ContextModel {
|
||||||
|
|
@ -9,6 +12,14 @@ pub struct ContextModel {
|
||||||
is_done: bool,
|
is_done: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct LoadSmartCollectionDto {
|
||||||
|
pub key: String,
|
||||||
|
pub order: SearchQueryOrder,
|
||||||
|
pub smart_collection: String,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct SearchQueryDto {
|
pub struct SearchQueryDto {
|
||||||
pub key: String,
|
pub key: String,
|
||||||
|
|
@ -47,3 +58,21 @@ pub enum FillerKind {
|
||||||
Midroll,
|
Midroll,
|
||||||
Postroll,
|
Postroll,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct ScheduleContentUntilDto {
|
||||||
|
#[serde(rename = "content")]
|
||||||
|
pub content_key: String,
|
||||||
|
pub when: String,
|
||||||
|
pub tomorrow: bool,
|
||||||
|
pub filler_kind: FillerKind,
|
||||||
|
pub custom_title: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
#[serde(rename_all = "camelCase")]
|
||||||
|
pub struct WaitUntilTimeDto {
|
||||||
|
pub rewind_on_reset: bool,
|
||||||
|
pub when: String,
|
||||||
|
}
|
||||||
|
|
|
||||||
133
src/main.rs
133
src/main.rs
|
|
@ -1,43 +1,150 @@
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use tv_scheduler::{
|
use tv_scheduler::{
|
||||||
config::Args,
|
config::{Args, ContentType, ScheduleBlock, ScheduleConfig, ScheduleType},
|
||||||
ersatz_tv::{
|
ersatz_tv::{
|
||||||
self,
|
self,
|
||||||
models::{
|
models::{
|
||||||
FillerKind, ScheduleAllContentDto, SearchQueryDto, SearchQueryOrder, SearchQueryValue,
|
FillerKind, LoadSmartCollectionDto, ScheduleAllContentDto, ScheduleContentUntilDto,
|
||||||
|
SearchQueryDto, SearchQueryOrder, SearchQueryValue, WaitUntilTimeDto,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
jellyfin,
|
jellyfin,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
async fn handle_schedule_block(
|
||||||
|
tv: &ersatz_tv::Client,
|
||||||
|
jelly: &jellyfin::Client,
|
||||||
|
block: &ScheduleBlock,
|
||||||
|
) -> anyhow::Result<()> {
|
||||||
|
println!("{:#?}", block);
|
||||||
|
|
||||||
|
// add pre content until time
|
||||||
|
if let Some(content) = &block.pre_filler {
|
||||||
|
let payload = match &content.content_type {
|
||||||
|
ContentType::SmartCollection { name } => LoadSmartCollectionDto {
|
||||||
|
key: name.clone(),
|
||||||
|
order: SearchQueryOrder::Chronological,
|
||||||
|
smart_collection: name.clone(),
|
||||||
|
},
|
||||||
|
ContentType::RandomAlbum {
|
||||||
|
container_id,
|
||||||
|
album_name_as_title,
|
||||||
|
} => todo!(),
|
||||||
|
};
|
||||||
|
|
||||||
|
println!("Loading PreFiller: {:#?}", payload);
|
||||||
|
tv.post("add_smart_collection", &payload).await?;
|
||||||
|
|
||||||
|
match &block.schedule_type {
|
||||||
|
ScheduleType::All => todo!(),
|
||||||
|
ScheduleType::StartAt {
|
||||||
|
time,
|
||||||
|
until_tomorrow,
|
||||||
|
} => {
|
||||||
|
tv.post(
|
||||||
|
"pad_until",
|
||||||
|
&ScheduleContentUntilDto {
|
||||||
|
content_key: payload.key,
|
||||||
|
when: time.clone(),
|
||||||
|
tomorrow: *until_tomorrow,
|
||||||
|
filler_kind: FillerKind::Preroll,
|
||||||
|
custom_title: content.custom_title.clone(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if let ScheduleType::StartAt {
|
||||||
|
time,
|
||||||
|
until_tomorrow: _,
|
||||||
|
} = &block.schedule_type
|
||||||
|
{
|
||||||
|
// Fill with nothing until the desire time
|
||||||
|
tv.post(
|
||||||
|
"wait_until_exact",
|
||||||
|
&WaitUntilTimeDto {
|
||||||
|
when: time.clone(),
|
||||||
|
rewind_on_reset: false,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
// add main content
|
||||||
|
match &block.content_type {
|
||||||
|
ContentType::SmartCollection { name } => todo!(),
|
||||||
|
ContentType::RandomAlbum {
|
||||||
|
container_id,
|
||||||
|
album_name_as_title,
|
||||||
|
} => {
|
||||||
|
let item = jelly.get_random_vgm_album().await?;
|
||||||
|
println!("Using album: {}", item.name);
|
||||||
|
let songs = jelly.get_songs(item.id).await?;
|
||||||
|
|
||||||
|
let content_payload = songs.items.iter().map(|song| SearchQueryDto {
|
||||||
|
key: song.id.clone(),
|
||||||
|
order: SearchQueryOrder::Shuffle,
|
||||||
|
query: SearchQueryValue::SongTitle(format!(
|
||||||
|
r#"title:"{}" AND library_id:9"#,
|
||||||
|
song.name
|
||||||
|
)),
|
||||||
|
});
|
||||||
|
|
||||||
|
for content in content_payload {
|
||||||
|
tv.post("add_search", &content).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let schedule_payload = songs.items.iter().map(|song| ScheduleAllContentDto {
|
||||||
|
key: song.id.clone(),
|
||||||
|
custom_title: if *album_name_as_title {
|
||||||
|
item.name.clone()
|
||||||
|
} else {
|
||||||
|
"VGM".to_string()
|
||||||
|
},
|
||||||
|
disable_watermarks: false,
|
||||||
|
filler_kind: FillerKind::None,
|
||||||
|
});
|
||||||
|
|
||||||
|
for content in schedule_payload {
|
||||||
|
tv.post("add_all", &content).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add all post content
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
let config = ScheduleConfig::new(None)?;
|
||||||
let jelly = jellyfin::Client::new("https://media.hoshikusu.xyz")?;
|
|
||||||
|
|
||||||
let item = jelly.get_random_vgm_album().await?;
|
|
||||||
let songs = jelly.get_songs(item.id).await?;
|
|
||||||
|
|
||||||
let tv = ersatz_tv::Client::new(&args.host, &args.build_id)?;
|
let tv = ersatz_tv::Client::new(&args.host, &args.build_id)?;
|
||||||
|
let jelly = jellyfin::Client::new("https://media.hoshikusu.xyz")?;
|
||||||
|
|
||||||
let content_payload = songs.items.iter().map(|song| SearchQueryDto {
|
for block in config.blocks {
|
||||||
|
handle_schedule_block(&tv, &jelly, &block).await?;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ok(());
|
||||||
|
|
||||||
|
let _item = jelly.get_random_vgm_album().await?;
|
||||||
|
let _songs = jelly.get_songs(_item.id).await?;
|
||||||
|
|
||||||
|
let _content_payload = _songs.items.iter().map(|song| SearchQueryDto {
|
||||||
key: song.id.clone(),
|
key: song.id.clone(),
|
||||||
order: SearchQueryOrder::Chronological,
|
order: SearchQueryOrder::Chronological,
|
||||||
query: SearchQueryValue::SongTitle(format!(r#"title:"{}" AND library_id:9"#, song.name)),
|
query: SearchQueryValue::SongTitle(format!(r#"title:"{}" AND library_id:9"#, song.name)),
|
||||||
});
|
});
|
||||||
|
|
||||||
tv.load_content(content_payload).await?;
|
let _schedule_payload = _songs.items.iter().map(|song| ScheduleAllContentDto {
|
||||||
|
|
||||||
let schedule_payload = songs.items.iter().map(|song| ScheduleAllContentDto {
|
|
||||||
key: song.id.clone(),
|
key: song.id.clone(),
|
||||||
custom_title: song.name.clone(),
|
custom_title: song.name.clone(),
|
||||||
disable_watermarks: false,
|
disable_watermarks: false,
|
||||||
filler_kind: FillerKind::None,
|
filler_kind: FillerKind::None,
|
||||||
});
|
});
|
||||||
|
|
||||||
tv.schedule_content(schedule_payload).await?;
|
|
||||||
|
|
||||||
// println!("{:#?}", songs);
|
// println!("{:#?}", songs);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue