project shared added

This commit is contained in:
euzu
2025-06-19 12:45:55 +02:00
parent b0897e99ef
commit 2a9c8711e6
177 changed files with 4178 additions and 380 deletions
+1
View File
@@ -1,3 +1,4 @@
dist
/resources/*.ts
/release
/target
Generated
+61 -58
View File
@@ -143,9 +143,9 @@ dependencies = [
[[package]]
name = "async-compression"
version = "0.4.24"
version = "0.4.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d615619615a650c571269c00dca41db04b9210037fa76ed8239f70404ab56985"
checksum = "40f6024f3f856663b45fd0c9b6f2024034a702f453549449e0d84a305900dad4"
dependencies = [
"brotli",
"flate2",
@@ -165,9 +165,9 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0"
[[package]]
name = "autocfg"
version = "1.4.0"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "axum"
@@ -368,9 +368,9 @@ checksum = "a2698f953def977c68f935bb0dfa959375ad4638570e969e2f1e9f433cbf1af6"
[[package]]
name = "cc"
version = "1.2.26"
version = "1.2.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "956a5e21988b87f372569b66183b78babf23ebc2e744b733e4350a752c4dafac"
checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc"
dependencies = [
"jobserver",
"libc",
@@ -995,7 +995,7 @@ dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi 0.11.0+wasi-snapshot-preview1",
"wasi 0.11.1+wasi-snapshot-preview1",
"wasm-bindgen",
]
@@ -1457,9 +1457,9 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]]
name = "jiff"
version = "0.2.14"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a194df1107f33c79f4f93d02c80798520551949d59dfad22b6157048a88cca93"
checksum = "be1f93b8b1eb69c77f24bbb0afdf66f54b632ee39af40ca21c4365a1d7347e49"
dependencies = [
"jiff-static",
"log",
@@ -1470,9 +1470,9 @@ dependencies = [
[[package]]
name = "jiff-static"
version = "0.2.14"
version = "0.2.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c6e1db7ed32c6c71b759497fae34bf7933636f75a251b9e736555da426f6442"
checksum = "03343451ff899767262ec32146f6d559dd759fdadf42ff0e227c7c48f72594b4"
dependencies = [
"proc-macro2",
"quote",
@@ -1542,9 +1542,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libc"
version = "0.2.172"
version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "libnghttp2-sys"
@@ -1627,9 +1627,9 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
[[package]]
name = "memchr"
version = "2.7.4"
version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "mime"
@@ -1664,7 +1664,7 @@ checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
dependencies = [
"libc",
"log",
"wasi 0.11.0+wasi-snapshot-preview1",
"wasi 0.11.1+wasi-snapshot-preview1",
"windows-sys 0.59.0",
]
@@ -1914,9 +1914,9 @@ checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
[[package]]
name = "pest"
version = "2.8.0"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "198db74531d58c70a361c42201efde7e2591e976d518caf7662a47dc5720e7b6"
checksum = "1db05f56d34358a8b1066f67cbb203ee3e7ed2ba674a6263a1d5ec6db2204323"
dependencies = [
"memchr",
"thiserror 2.0.12",
@@ -1925,9 +1925,9 @@ dependencies = [
[[package]]
name = "pest_derive"
version = "2.8.0"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d725d9cfd79e87dccc9341a2ef39d1b6f6353d68c4b33c177febbe1a402c97c5"
checksum = "bb056d9e8ea77922845ec74a1c4e8fb17e7c218cc4fc11a15c5d25e189aa40bc"
dependencies = [
"pest",
"pest_generator",
@@ -1935,9 +1935,9 @@ dependencies = [
[[package]]
name = "pest_generator"
version = "2.8.0"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db7d01726be8ab66ab32f9df467ae8b1148906685bbe75c82d1e65d7f5b3f841"
checksum = "87e404e638f781eb3202dc82db6760c8ae8a1eeef7fb3fa8264b2ef280504966"
dependencies = [
"pest",
"pest_meta",
@@ -1948,11 +1948,10 @@ dependencies = [
[[package]]
name = "pest_meta"
version = "2.8.0"
version = "2.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f9f832470494906d1fca5329f8ab5791cc60beb230c74815dff541cbd2b5ca0"
checksum = "edd1101f170f5903fde0914f899bb503d9ff5271d7ba76bbb70bea63690cc0d5"
dependencies = [
"once_cell",
"pest",
"sha2",
]
@@ -2061,15 +2060,15 @@ dependencies = [
[[package]]
name = "quanta"
version = "0.12.5"
version = "0.12.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bd1fe6824cea6538803de3ff1bc0cf3949024db3d43c9643024bfb33a807c0e"
checksum = "f3ab5a9d756f0d97bdc89019bd2e4ea098cf9cde50ee7564dde6b81ccc8f06c7"
dependencies = [
"crossbeam-utils",
"libc",
"once_cell",
"raw-cpuid",
"wasi 0.11.0+wasi-snapshot-preview1",
"wasi 0.11.1+wasi-snapshot-preview1",
"web-sys",
"winapi",
]
@@ -2126,9 +2125,9 @@ dependencies = [
[[package]]
name = "quinn-udp"
version = "0.5.12"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee4e529991f949c5e25755532370b8af5d114acae52326361d68d47af64aa842"
checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970"
dependencies = [
"cfg_aliases",
"libc",
@@ -2149,9 +2148,9 @@ dependencies = [
[[package]]
name = "r-efi"
version = "5.2.0"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "rand"
@@ -2213,9 +2212,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.5.12"
version = "0.5.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "928fca9cf2aa042393a8325b9ead81d2f0df4cb12e1e24cef072922ccd99c5af"
checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
dependencies = [
"bitflags 2.9.1",
]
@@ -2251,9 +2250,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "reqwest"
version = "0.12.19"
version = "0.12.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2f8e5513d63f2e5b386eb5106dc67eaf3f84e95258e210489136b8b92ad6119"
checksum = "eabf4c97d9130e2bf606614eb937e86edac8292eaa6f422f995d7e8de1eb1813"
dependencies = [
"base64 0.22.1",
"bytes",
@@ -2269,12 +2268,10 @@ dependencies = [
"hyper-rustls",
"hyper-tls",
"hyper-util",
"ipnet",
"js-sys",
"log",
"mime",
"native-tls",
"once_cell",
"percent-encoding",
"pin-project-lite",
"quinn",
@@ -2400,9 +2397,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.23.27"
version = "0.23.28"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "730944ca083c1c233a75c09f199e973ca499344a2b7ba9e755c457e86fb4a321"
checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643"
dependencies = [
"once_cell",
"ring",
@@ -2579,6 +2576,14 @@ dependencies = [
"digest",
]
[[package]]
name = "shared"
version = "0.1.0"
dependencies = [
"bitflags 2.9.1",
"serde",
]
[[package]]
name = "shlex"
version = "1.3.0"
@@ -2599,12 +2604,9 @@ dependencies = [
[[package]]
name = "slab"
version = "0.4.9"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f92a496fb766b417c996b9c5e57daf2f7ad3b0bebe1ccfca4856390e3d3bb67"
dependencies = [
"autocfg",
]
checksum = "04dc19736151f35336d325007ac991178d504a119863a2fcb3758cdb5e52c50d"
[[package]]
name = "sluice"
@@ -2662,9 +2664,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
[[package]]
name = "syn"
version = "2.0.102"
version = "2.0.103"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f6397daf94fa90f058bd0fd88429dd9e5738999cca8d701813c80723add80462"
checksum = "e4307e30089d6fd6aff212f2da3a1f9e32f3223b1f010fb09b7c95f90f3ca1e8"
dependencies = [
"proc-macro2",
"quote",
@@ -2984,9 +2986,9 @@ dependencies = [
[[package]]
name = "tracing-attributes"
version = "0.1.29"
version = "0.1.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b1ffbcf9c6f6b99d386e7444eb608ba646ae452a36b39737deb9663b610f662"
checksum = "81383ab64e72a7a8b8e13130c49e3dab29def6d0c7d76a03087b3cf71c5c6903"
dependencies = [
"proc-macro2",
"quote",
@@ -3024,7 +3026,7 @@ version = "3.1.4"
dependencies = [
"arc-swap",
"axum",
"base64 0.21.7",
"base64 0.22.1",
"bincode",
"bitflags 2.9.1",
"blake3",
@@ -3065,6 +3067,7 @@ dependencies = [
"serde",
"serde_json",
"serde_yaml",
"shared",
"socket2",
"strsim",
"tempfile",
@@ -3220,9 +3223,9 @@ dependencies = [
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
version = "0.11.1+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
[[package]]
name = "wasi"
@@ -3414,9 +3417,9 @@ dependencies = [
[[package]]
name = "windows-link"
version = "0.1.1"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a"
[[package]]
name = "windows-registry"
@@ -3645,18 +3648,18 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.8.25"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a1702d9583232ddb9174e01bb7c15a2ab8fb1bc6f227aa1233858c351a3ba0cb"
checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.8.25"
version = "0.8.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28a6e20d751156648aa063f3800b706ee209a32c0b4d9f24be3d980b01be55ef"
checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181"
dependencies = [
"proc-macro2",
"quote",
+3 -69
View File
@@ -1,7 +1,6 @@
[package]
name = "tuliprox"
version = "3.1.4"
edition = "2021"
[workspace]
members = ["backend", "shared"]
resolver = "2"
[profile.release]
debug = false
@@ -11,68 +10,3 @@ codegen-units = 1 # Reduce number of codegen units to increase optimizations.
panic = 'abort' # Abort on panic
strip = true
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { version = "1.0", features = ["derive", "rc"] }
serde_yaml = "0.9"
serde_json = { version = "1", features = ["arbitrary_precision"] }
quick-xml = "0.37"
regex = "1.11"
clap = { version = "4", features = ["derive"] }
url = "2.5"
reqwest = { version = "0", features = ["blocking", "json", "stream", "rustls-tls"] }
chrono = "0.4"
cron = "0.15"
axum = { version = "0" , features = ["macros", "default"]}
tower = "0"
tower-http = { version = "0", features = ["cors", "auth", "fs", "compression-full"]}
tower_governor = { version = "0.7", features = ["axum"] }
jsonwebtoken = "9.3"
rust-argon2 = "2.1"
futures = "0.3"
path-clean = "1"
pest = "2.8"
pest_derive = "2.8"
enum-iterator = "2"
openssl = { version = "*", features = ["vendored"] } #https://docs.rs/openssl/0.10.34/openssl/#vendored
deunicode = "1.6.2"
mime = "0.3"
log = "0.4"
env_logger = "0.11"
rustelebot = "0.3"
bincode = { version = "2.0.1", features = ["std", "serde"] }
rand = "0.9"
rpassword = "7.4"
flate2 = "1"
blake3 = "1.8"
bytes = "1.10"
tokio-stream = { version = "0.1", features = ["sync"] }
tokio = { version = "1.45", features = ["rt-multi-thread", "parking_lot", "fs"] }
tokio-util = "0.7"
tempfile = "3.20"
ruzstd = "0"
filetime = "0.2"
zeroize = "1.8"
strsim = "0.11"
rphonetic = "3"
rayon = "1.10"
base64 = "0"
paste = "1"
bitflags = "2"
indexmap = "2"
notify = "8"
arc-swap = "1"
dashmap = "6"
hyper = "1"
hyper-util = "0"
socket2 = "0"
#[cfg(target_os = "macos")]
libc = "0"
#[cfg(target_os = "windows")]
winapi = { version = "0", features = ["psapi", "minwindef", "processthreadsapi"] }
# [target.'cfg(not(target_env = "msvc"))'.dependencies]
# tikv-jemallocator = { version = "*", features = ["profiling", "unprefixed_malloc_on_supported_platforms"] }
[build-dependencies]
vergen = { version = "9", features = ["build"] }
+3752
View File
File diff suppressed because it is too large Load Diff
+71
View File
@@ -0,0 +1,71 @@
[package]
name = "tuliprox"
version = "3.1.4"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
shared = {version = "0", path = "../shared" }
serde = { version = "1.0", features = ["derive", "rc"] }
serde_yaml = "0.9"
serde_json = { version = "1", features = ["arbitrary_precision"] }
quick-xml = "0.37"
regex = "1.11"
clap = { version = "4", features = ["derive"] }
url = "2.5"
reqwest = { version = "0", features = ["blocking", "json", "stream", "rustls-tls"] }
chrono = "0.4"
cron = "0.15"
axum = { version = "0" , features = ["macros", "default"]}
tower = "0"
tower-http = { version = "0", features = ["cors", "auth", "fs", "compression-full"]}
tower_governor = { version = "0.7", features = ["axum"] }
jsonwebtoken = "9.3"
rust-argon2 = "2.1"
futures = "0.3"
path-clean = "1"
pest = "2.8"
pest_derive = "2.8"
enum-iterator = "2"
openssl = { version = "*", features = ["vendored"] } #https://docs.rs/openssl/0.10.34/openssl/#vendored
deunicode = "1.6.2"
mime = "0.3"
log = "0.4"
env_logger = "0.11"
rustelebot = "0.3"
bincode = { version = "2.0.1", features = ["std", "serde"] }
rand = "0.9"
rpassword = "7.4"
flate2 = "1"
blake3 = "1.8"
bytes = "1.10"
tokio-stream = { version = "0.1", features = ["sync"] }
tokio = { version = "1.45", features = ["rt-multi-thread", "parking_lot", "fs"] }
tokio-util = "0.7"
tempfile = "3.20"
ruzstd = "0"
filetime = "0.2"
zeroize = "1.8"
strsim = "0.11"
rphonetic = "3"
rayon = "1.10"
base64 = "0"
paste = "1"
bitflags = "2"
indexmap = "2"
notify = "8"
arc-swap = "1"
dashmap = "6"
hyper = "1"
hyper-util = "0"
socket2 = "0"
#[cfg(target_os = "macos")]
libc = "0"
#[cfg(target_os = "windows")]
winapi = { version = "0", features = ["psapi", "minwindef", "processthreadsapi"] }
# [target.'cfg(not(target_env = "msvc"))'.dependencies]
# tikv-jemallocator = { version = "*", features = ["profiling", "unprefixed_malloc_on_supported_platforms"] }
[build-dependencies]
vergen = { version = "9", features = ["build"] }
View File
@@ -14,7 +14,7 @@ use crate::api::model::streams::throttled_stream::ThrottledStream;
use crate::auth::Claims;
use crate::model::{ProxyUserCredentials, UserConnectionPermission};
use crate::model::{ConfigInput, ConfigTarget, InputFetchMethod, TargetType};
use crate::model::{PlaylistEntry, PlaylistItemType, XtreamCluster};
use shared::model::{PlaylistEntry, PlaylistItemType, XtreamCluster};
use crate::tools::atomic_once_flag::AtomicOnceFlag;
use crate::tools::lru_cache::LRUResourceCache;
use crate::utils::{DASH_EXT, HLS_EXT};
@@ -1,5 +1,6 @@
use crate::model::{Config, ConfigInput, ConfigTarget, InputType, TargetType};
use crate::model::{M3uPlaylistItem, PlaylistGroup, PlaylistItemType, XtreamCluster};
use crate::model::{M3uPlaylistItem, PlaylistGroup};
use shared::model::{PlaylistItemType, XtreamCluster};
use crate::repository::{m3u_repository, xtream_repository};
use crate::utils::{m3u, xtream};
use axum::response::IntoResponse;
@@ -2,7 +2,8 @@ use crate::api::model::app_state::HdHomerunAppState;
use crate::auth::AuthBasic;
use crate::model::ProxyUserCredentials;
use crate::model::{Config, ConfigTarget, TargetType};
use crate::model::{M3uPlaylistItem, PlaylistItemType, XtreamCluster, XtreamPlaylistItem};
use crate::model::{M3uPlaylistItem, XtreamPlaylistItem};
use shared::model::{PlaylistItemType, XtreamCluster};
use crate::processing::parser::xtream::get_xtream_url;
use crate::repository::m3u_playlist_iterator::M3uPlaylistIterator;
use crate::repository::xtream_playlist_iterator::XtreamPlaylistIterator;
@@ -4,7 +4,7 @@ use crate::api::model::app_state::AppState;
use crate::api::model::streams::provider_stream::{create_custom_video_stream_response, CustomVideoStreamType};
use crate::model::{ProxyUserCredentials, UserConnectionPermission};
use crate::model::ConfigInput;
use crate::model::{PlaylistItemType, XtreamCluster};
use shared::model::{PlaylistItemType, XtreamCluster};
use crate::processing::parser::hls::{get_hls_session_token_and_url_from_token, rewrite_hls, RewriteHlsProps};
use crate::utils::HLS_EXT;
use crate::utils::request;
@@ -6,7 +6,7 @@ use crate::api::model::request::UserApiRequest;
use crate::api::model::streams::provider_stream::{create_custom_video_stream_response, CustomVideoStreamType};
use crate::model::TargetType;
use crate::model::UserConnectionPermission;
use crate::model::{FieldGetAccessor, PlaylistEntry, PlaylistItemType, XtreamCluster};
use shared::model::{FieldGetAccessor, PlaylistEntry, PlaylistItemType, XtreamCluster};
use crate::repository::m3u_repository::{m3u_get_item_for_stream_id, m3u_load_rewrite_playlist};
use crate::repository::storage_const;
use crate::utils::request::{extract_extension_from_url, sanitize_sensitive_info};
@@ -2,7 +2,7 @@ use crate::api::api_utils::{get_user_target_by_username, get_username_from_auth_
use crate::api::model::app_state::AppState;
use crate::auth::validator_user;
use crate::model::{Config, ConfigTarget, TargetType};
use crate::model::XtreamCluster;
use shared::model::XtreamCluster;
use crate::model::PlaylistBouquetDto;
use crate::model::PlaylistXtreamCategory;
use crate::repository::user_repository::{load_user_bouquet_as_json, save_user_bouquet};
@@ -10,16 +10,16 @@ use crate::api::model::request::UserApiRequest;
use crate::api::model::streams::provider_stream::{create_custom_video_stream_response, CustomVideoStreamType};
use crate::api::model::xtream::XtreamAuthorizationResponse;
use crate::model::TargetType;
use crate::model::{get_backdrop_path_value, FieldGetAccessor, PlaylistEntry, PlaylistItemType, XtreamCluster, XtreamPlaylistItem};
use crate::model::{get_backdrop_path_value, XtreamPlaylistItem};
use crate::model::{Config, ConfigInput, ConfigTarget};
use crate::model::{ProxyType, ProxyUserCredentials, UserConnectionPermission};
use crate::repository::playlist_repository::get_target_id_mapping;
use crate::repository::storage::{get_target_storage_path, hex_encode};
use crate::repository::storage::{get_target_storage_path};
use crate::repository::{storage_const, user_repository, xtream_repository};
use crate::tuliprox_error::create_tuliprox_error_result;
use crate::tuliprox_error::info_err;
use crate::tuliprox_error::{str_to_io_error, TuliproxError, TuliproxErrorKind};
use crate::utils::generate_playlist_uuid;
use crate::utils::{generate_playlist_uuid, hex_encode};
use crate::utils::get_u32_from_serde_value;
use crate::utils::request::{extract_extension_from_url, sanitize_sensitive_info};
use crate::utils::trace_if_enabled;
@@ -41,6 +41,7 @@ use std::fmt::{Display, Formatter};
use std::path::Path;
use std::str::FromStr;
use std::sync::Arc;
use shared::model::{PlaylistItemType, XtreamCluster, FieldGetAccessor, PlaylistEntry};
#[derive(Serialize, Deserialize, Debug, Copy, Clone, Eq, PartialEq)]
pub enum ApiStreamContext {
@@ -7,7 +7,7 @@ use deunicode::deunicode;
use serde::{Deserialize, Serialize};
use crate::model::{VideoDownloadConfig};
use crate::repository::storage::hash_string_as_hex;
use crate::utils::hash_string_as_hex;
use crate::utils::{CONSTANTS, FILENAME_TRIM_PATTERNS};
/// File-Download information.
@@ -1,7 +1,7 @@
use crate::api::api_utils::{HeaderFilter};
use crate::api::model::streams::custom_video_stream::CustomVideoStream;
use crate::model::{Config};
use crate::model::PlaylistItemType;
use shared::model::PlaylistItemType;
use log::{trace};
use reqwest::StatusCode;
use axum::response::IntoResponse;
@@ -6,7 +6,7 @@ use crate::api::model::streams::buffered_stream::BufferedStream;
use crate::api::model::streams::client_stream::ClientStream;
use crate::api::model::streams::provider_stream::{create_channel_unavailable_stream, get_header_filter_for_item_type};
use crate::api::model::streams::timed_client_stream::TimedClientStream;
use crate::model::PlaylistItemType;
use shared::model::PlaylistItemType;
use crate::model::{Config, DEFAULT_USER_AGENT};
use crate::tools::atomic_once_flag::AtomicOnceFlag;
use crate::utils::request::{classify_content_type, get_request_headers, sanitize_sensitive_info, MimeCategory};
@@ -1,4 +1,4 @@
use crate::repository::storage::{hex_decode, hex_encode};
use crate::utils::{hex_decode, hex_encode};
use chrono::Utc;
use serde::{Deserialize, Serialize};
@@ -8,8 +8,8 @@ use pest::iterators::Pair;
use pest::Parser;
use std::cmp::Ordering;
use std::collections::HashMap;
use crate::model::{FieldGetAccessor, FieldSetAccessor, ItemField};
use crate::model::{PlaylistItem, PlaylistItemType};
use shared::model::{FieldGetAccessor, FieldSetAccessor, PlaylistItemType};
use crate::model::{PlaylistItem, ItemField};
use crate::tools::directed_graph::DirectedGraph;
use crate::tuliprox_error::{create_tuliprox_error_result, info_err};
use crate::tuliprox_error::{TuliproxError, TuliproxErrorKind};
View File
@@ -1,6 +1,6 @@
use crate::api::model::app_state::AppState;
use crate::tuliprox_error::{create_tuliprox_error_result, info_err, TuliproxError, TuliproxErrorKind};
use crate::model::{Config, ClusterFlags};
use crate::model::{Config};
use crate::repository::user_repository::{backup_api_user_db_file, get_api_user_db_path, load_api_user, merge_api_user};
use crate::utils::{default_as_true, save_api_proxy};
use chrono::Local;
@@ -12,7 +12,7 @@ use std::fmt::Display;
use std::fs;
use std::str::FromStr;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use crate::model::PlaylistItemType;
use shared::model::{PlaylistItemType, ClusterFlags};
use crate::utils;
#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize, PartialEq, Eq)]
@@ -1,19 +1,30 @@
use crate::foundation::filter::{get_filter, Filter, PatternTemplate, ValueProvider};
use crate::tuliprox_error::{create_tuliprox_error_result, handle_tuliprox_error_result_list, info_err, TuliproxError, TuliproxErrorKind};
use crate::model::cluster_flags::ClusterFlags;
use crate::model::config_rename::ConfigRename;
use crate::model::config_sort::ConfigSort;
use crate::model::mapping::Mapping;
use crate::model::processing_order::ProcessingOrder;
use crate::model::PlaylistItemType;
use crate::model::trakt::TraktConfig;
use crate::tuliprox_error::{create_tuliprox_error_result, handle_tuliprox_error_result_list, info_err, TuliproxError, TuliproxErrorKind};
use crate::utils::{default_as_default, default_as_true, default_resolve_delay_secs};
use arc_swap::ArcSwapOption;
use enum_iterator::Sequence;
use shared::model::ClusterFlags;
use shared::model::PlaylistItemType;
use std::fmt::Display;
use std::sync::Arc;
use arc_swap::{ArcSwapOption};
#[derive(Debug, Copy, Clone, serde::Serialize, serde::Deserialize, Sequence, PartialEq, Eq, Hash, Default)]
#[derive(
Debug,
Copy,
Clone,
serde::Serialize,
serde::Deserialize,
Sequence,
PartialEq,
Eq,
Hash,
Default
)]
pub enum ExportStyle {
#[serde(rename = "kodi")]
#[default]
@@ -184,7 +195,7 @@ pub enum TargetOutput {
impl TargetOutput {
pub fn prepare(&mut self) {
match self {
match self {
TargetOutput::Xtream(output) => output.prepare(),
TargetOutput::M3u(_)
| TargetOutput::Strm(_)
@@ -257,7 +268,7 @@ impl ConfigTarget {
m3u_output.filename = m3u_output.filename.as_ref().map(|s| s.trim().to_string());
}
TargetOutput::Strm(strm_output) => {
strm_cnt +=1;
strm_cnt += 1;
strm_output.directory = strm_output.directory.trim().to_string();
if strm_output.directory.trim().is_empty() {
return create_tuliprox_error_result!(TuliproxErrorKind::Info, "directory is required for strm type: {}", self.name);
@@ -14,7 +14,6 @@ mod config_ip_check;
mod config_sort;
mod config_rename;
mod processing_order;
mod cluster_flags;
mod config_target;
mod config_source;
mod config_proxy;
@@ -29,8 +28,6 @@ mod config_healthcheck;
mod config_cache;
mod trakt;
// Re-export modules for easier access
pub use self::config_cache::*;
pub use self::config::*;
pub use self::playlist::*;
pub use self::mapping::*;
@@ -46,7 +43,6 @@ pub use self::config_ip_check::*;
pub use self::config_sort::*;
pub use self::config_rename::*;
pub use self::processing_order::*;
pub use self::cluster_flags::*;
pub use self::config_target::*;
pub use self::config_source::*;
pub use self::config_proxy::*;
@@ -1,28 +1,16 @@
use crate::model::xtream::{xtream_playlistitem_to_document, XtreamMappingOptions};
use crate::model::xtream_const;
use crate::model::ProxyUserCredentials;
use crate::model::TVGuide;
use crate::model::{ConfigInput, ConfigTargetOptions};
use crate::model::{TVGuide, ProxyUserCredentials, ConfigInput, ConfigTargetOptions};
use crate::utils::request::extract_extension_from_url;
use crate::utils::{generate_playlist_uuid, get_provider_id};
use crate::utils::{get_string_from_serde_value, get_u64_from_serde_value};
use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use std::borrow::Cow;
use std::cmp::PartialEq;
use std::fmt::{Display, Formatter};
use std::str::FromStr;
use shared::model::{PlaylistEntry, PlaylistItemType, UUIDType, XtreamCluster};
// https://de.wikipedia.org/wiki/M3U
// https://siptv.eu/howto/playlist.html
pub trait PlaylistEntry: Send + Sync {
fn get_virtual_id(&self) -> u32;
fn get_provider_id(&self) -> Option<u32>;
fn get_category_id(&self) -> Option<u32>;
fn get_provider_url(&self) -> String;
fn get_uuid(&self) -> UUIDType;
fn get_item_type(&self) -> PlaylistItemType;
}
#[derive(Debug, Clone)]
pub struct FetchedPlaylist<'a> { // Contains playlist for one input
@@ -42,120 +30,6 @@ impl FetchedPlaylist<'_> {
}
}
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, Serialize, Deserialize, Default)]
#[repr(u8)]
pub enum XtreamCluster {
#[default]
Live = 1,
Video = 2,
Series = 3,
}
impl XtreamCluster {
pub const fn as_str(&self) -> &str {
match self {
Self::Live => "Live",
Self::Video => "Video",
Self::Series => "Series",
}
}
pub const fn as_stream_type(&self) -> &str {
match self {
Self::Live => "live",
Self::Video => "movie",
Self::Series => "series",
}
}
}
impl Display for XtreamCluster {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.as_str())
}
}
impl TryFrom<PlaylistItemType> for XtreamCluster {
type Error = String;
fn try_from(item_type: PlaylistItemType) -> Result<Self, Self::Error> {
match item_type {
PlaylistItemType::Live | PlaylistItemType::LiveHls | PlaylistItemType::LiveDash | PlaylistItemType::LiveUnknown => Ok(Self::Live),
PlaylistItemType::Catchup | PlaylistItemType::Video => Ok(Self::Video),
PlaylistItemType::Series | PlaylistItemType::SeriesInfo => Ok(Self::Series),
}
}
}
#[derive(Debug, Copy, Clone, Eq, Hash, PartialEq, Serialize, Deserialize, Default)]
#[repr(u8)]
pub enum PlaylistItemType {
#[default]
Live = 1,
Video = 2,
Series = 3, // xtream series description
SeriesInfo = 4, // xtream series info fetched for series description
Catchup = 5,
LiveUnknown = 6, // No Provider id
LiveHls = 7, // m3u8 entry
LiveDash = 8, // mpd
}
impl From<XtreamCluster> for PlaylistItemType {
fn from(xtream_cluster: XtreamCluster) -> Self {
match xtream_cluster {
XtreamCluster::Live => Self::Live,
XtreamCluster::Video => Self::Video,
XtreamCluster::Series => Self::SeriesInfo,
}
}
}
impl FromStr for PlaylistItemType {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"Live" => Ok(PlaylistItemType::Live),
"Video" => Ok(PlaylistItemType::Video),
"Series" => Ok(PlaylistItemType::Series),
"SeriesInfo" => Ok(PlaylistItemType::SeriesInfo),
"Catchup" => Ok(PlaylistItemType::Catchup),
"LiveUnknown" => Ok(PlaylistItemType::LiveUnknown),
"LiveHls" => Ok(PlaylistItemType::LiveHls),
"LiveDash" => Ok(PlaylistItemType::LiveDash),
_ => Err(format!("Invalid PlaylistItemType: {s}")),
}
}
}
impl PlaylistItemType {
const LIVE: &'static str = "live";
const VIDEO: &'static str = "video";
const SERIES: &'static str = "series";
const SERIES_INFO: &'static str = "series-info";
const CATCHUP: &'static str = "catchup";
}
impl Display for PlaylistItemType {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", match self {
Self::Live | Self::LiveHls | Self::LiveDash | Self::LiveUnknown => Self::LIVE,
Self::Video => Self::VIDEO,
Self::Series => Self::SERIES,
Self::SeriesInfo => Self::SERIES_INFO,
Self::Catchup => Self::CATCHUP,
})
}
}
pub trait FieldGetAccessor {
fn get_field(&self, field: &str) -> Option<Cow<str>>;
}
pub trait FieldSetAccessor {
fn set_field(&mut self, field: &str, value: &str) -> bool;
}
pub type UUIDType = [u8; 32];
#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct PlaylistItemHeader {
@@ -252,7 +126,7 @@ macro_rules! to_m3u_resource_non_empty_fields {
macro_rules! generate_field_accessor_impl_for_playlist_item_header {
($($prop:ident),*;) => {
impl FieldGetAccessor for PlaylistItemHeader {
impl shared::model::FieldGetAccessor for PlaylistItemHeader {
fn get_field(&self, field: &str) -> Option<Cow<str>> {
let field = field.to_lowercase();
match field.as_str() {
@@ -267,7 +141,7 @@ macro_rules! generate_field_accessor_impl_for_playlist_item_header {
}
}
}
impl FieldSetAccessor for PlaylistItemHeader {
impl shared::model::FieldSetAccessor for PlaylistItemHeader {
fn set_field(&mut self, field: &str, value: &str) -> bool {
let field = field.to_lowercase();
let val = String::from(value);
@@ -379,7 +253,7 @@ impl PlaylistEntry for M3uPlaylistItem {
macro_rules! generate_field_accessor_impl_for_m3u_playlist_item {
($($prop:ident),*;) => {
impl FieldGetAccessor for M3uPlaylistItem {
impl shared::model::FieldGetAccessor for M3uPlaylistItem {
fn get_field(&self, field: &str) -> Option<Cow<str>> {
let field = field.to_lowercase();
match field.as_str() {
@@ -490,7 +364,7 @@ pub fn get_backdrop_path_value<'a>(field: &'a str, value: Option<&'a Value>) ->
macro_rules! generate_field_accessor_impl_for_xtream_playlist_item {
($($prop:ident),*;) => {
impl FieldGetAccessor for XtreamPlaylistItem {
impl shared::model::FieldGetAccessor for XtreamPlaylistItem {
fn get_field(&self, field: &str) -> Option<Cow<str>> {
let field = field.to_lowercase();
match field.as_str() {
@@ -1,6 +1,6 @@
use crate::model::{ProxyUserCredentials};
use crate::model::{Config, ConfigTarget, ClusterFlags, XtreamTargetOutput};
use crate::model::{PlaylistEntry, PlaylistItem, XtreamCluster, XtreamPlaylistItem};
use crate::model::{Config, ConfigTarget, XtreamTargetOutput};
use crate::model::{PlaylistItem,XtreamPlaylistItem};
use crate::model::serde_utils::{deserialize_as_option_rc_string, deserialize_as_rc_string, deserialize_as_string_array, deserialize_number_from_string};
use crate::model::xtream_const;
use crate::utils::{get_non_empty_str, opt_string_or_number_u32, string_default_on_null, string_or_number_f64, string_or_number_u32};
@@ -8,7 +8,7 @@ use serde::{Deserialize, Serialize};
use serde_json::{Map, Value};
use std::collections::HashMap;
use std::iter::FromIterator;
use shared::model::{ClusterFlags, PlaylistEntry, XtreamCluster};
#[derive(Deserialize, Default)]
pub struct XtreamCategory {
@@ -1,6 +1,7 @@
use std::borrow::BorrowMut;
use shared::model::{PlaylistItemType, XtreamCluster};
use crate::model::{Config, ConfigInput};
use crate::model::{PlaylistGroup, PlaylistItem, PlaylistItemHeader, PlaylistItemType, XtreamCluster};
use crate::model::{PlaylistGroup, PlaylistItem, PlaylistItemHeader};
use crate::utils::{extract_id_from_url, get_title_group};
#[inline]
@@ -1,12 +1,13 @@
use crate::tuliprox_error::{create_tuliprox_error_result, TuliproxError, TuliproxErrorKind};
use crate::model::ConfigInput;
use crate::model::{PlaylistGroup, PlaylistItem, PlaylistItemHeader, PlaylistItemType, XtreamCluster};
use crate::model::{PlaylistGroup, PlaylistItem, PlaylistItemHeader};
use crate::model::{XtreamCategory, XtreamSeriesInfo, XtreamSeriesInfoEpisode, XtreamStream};
use crate::utils::generate_playlist_uuid;
use crate::utils::xtream::{get_xtream_stream_url_base};
use serde_json::Value;
use std::collections::HashMap;
use std::sync::Arc;
use shared::model::{PlaylistItemType, XtreamCluster};
fn map_to_xtream_category(categories: &Value) -> Result<Vec<XtreamCategory>, TuliproxError> {
match serde_json::from_value::<Vec<XtreamCategory>>(categories.to_owned()) {

Some files were not shown because too many files have changed in this diff Show More