tuliprox: init at 3.1.7 (#453861)

This commit is contained in:
Sandro
2025-11-23 04:06:06 +00:00
committed by GitHub
5 changed files with 441 additions and 0 deletions
+1
View File
@@ -1728,6 +1728,7 @@
./services/web-apps/suwayomi-server.nix
./services/web-apps/szurubooru.nix
./services/web-apps/trilium.nix
./services/web-apps/tuliprox.nix
./services/web-apps/umami.nix
./services/web-apps/vikunja.nix
./services/web-apps/wakapi.nix
@@ -0,0 +1,336 @@
{
config,
pkgs,
lib,
utils,
...
}:
let
cfg = config.services.tuliprox;
settingsFormat = pkgs.formats.yaml { };
systemSettingsYaml = settingsFormat.generate "config.yml" cfg.systemSettings;
sourceSettingsYaml = settingsFormat.generate "source.yml" cfg.sourceSettings;
apiProxySettingsYaml = settingsFormat.generate "api-proxy.yml" cfg.apiProxySettings;
mappingSettingsYaml = settingsFormat.generate "mapping.yml" cfg.mappingSettings;
in
{
meta.maintainers = with lib.maintainers; [ nyanloutre ];
options.services.tuliprox = {
enable = lib.mkEnableOption "Tuliprox IPTV playlist processor & proxy";
package = lib.mkPackageOption pkgs "tuliprox" { };
extraArgs = lib.mkOption {
type = lib.types.listOf lib.types.str;
default = [ ];
description = ''
Additional command-line arguments for the systemd service.
Refer to the [Tuliprox documentation] for available arguments.
[Tuliprox documentation]: https://github.com/euzu/tuliprox?tab=readme-ov-file#command-line-arguments
'';
};
systemSettings = lib.mkOption {
type = settingsFormat.type;
example = {
api = {
host = "0.0.0.0";
port = 8901;
};
};
description = ''
Main config file
Refer to the [Tuliprox documentation] for available attributes
[Tuliprox documentation]: https://github.com/euzu/tuliprox?tab=readme-ov-file#1-configyml
'';
};
sourceSettings = lib.mkOption {
type = settingsFormat.type;
example = {
templates = [
{
name = "not_red_button";
value = "NOT (Title ~ \"(?i).*red button.*\")";
}
{
name = "not_low_resolution";
value = "NOT (Title ~ \"(?i).*\(360p|240p\).*\")";
}
{
name = "all_channels";
value = "Title ~ \".*\"";
}
{
name = "final_channel_lineup";
value = "!all_channels! AND !not_red_button! AND !not_low_resolution!";
}
];
sources = [
{
inputs = [
{
name = "iptv-org";
type = "m3u";
url = "https://iptv-org.github.io/iptv/countries/uk.m3u";
}
];
targets = [
{
name = "iptv-org";
output = [
{
type = "xtream";
}
{
type = "m3u";
filename = "iptv.m3u";
}
{
type = "hdhomerun";
username = "local";
device = "hdhr1";
}
];
filter = "!final_channel_lineup!";
options = {
ignore_logo = false;
share_live_streams = true;
};
mapping = [
"iptv-org"
];
}
];
}
];
};
description = ''
Source definitions
Refer to the [Tuliprox documentation] for available attributes
[Tuliprox documentation]: https://github.com/euzu/tuliprox?tab=readme-ov-file#2-sourceyml
'';
};
apiProxySettings = lib.mkOption {
type = settingsFormat.type;
example = {
server = [
{
name = "default";
protocol = "http";
host = "192.169.1.9";
port = 8901;
timezone = "Europe/Paris";
message = "Welcome to tuliprox";
}
{
name = "external";
protocol = "https";
host = "tuliprox.mydomain.tv";
port = 443;
timezone = "Europe/Paris";
message = "Welcome to tuliprox";
}
];
user = [
{
target = "xc_m3u";
credentials = [
{
username = "test1";
password = "secret1";
token = "token1";
proxy = "reverse";
server = "default";
exp_date = 1672705545;
max_connections = 1;
status = "Active";
}
];
}
];
};
description = ''
Users and proxy configuration
Refer to the [Tuliprox documentation] for available attributes
[Tuliprox documentation]: https://github.com/euzu/tuliprox?tab=readme-ov-file#3-api-proxy-config
'';
};
mappingSettings = lib.mkOption {
type = settingsFormat.type;
example = {
mappings = {
templates = [
{
name = "bbc";
value = "Title ~ \"^BBC\"";
}
{
name = "documentary";
value = "(Group ~ \"(Documentary|Outdoor)\")";
}
{
name = "entertainment";
value = "Group ~ \"Entertainment\"";
}
{
name = "pluto_tv";
value = "(Caption ~ \"Pluto TV\") AND NOT(Caption ~ \"Sports\")";
}
{
name = "business";
value = "Group ~ \"Business\"";
}
];
mapping = [
{
id = "iptv-org";
match_as_ascii = true;
mapper = [
{
filter = "!bbc!";
script = ''
@Group = "BBC"
'';
}
{
filter = "!documentary!";
script = ''
@Group = "Documentary"
'';
}
{
filter = "!entertainment!";
script = ''
@Group = "Entertainment"
'';
}
{
filter = "!pluto_tv!";
script = ''
@Group = "Pluto TV"
'';
}
{
filter = "!business!";
script = ''
@Group = "News"
'';
}
{
filter = "Input ~ \"iptv-org\"";
script = ''
@Caption = concat(@Caption, " (iptv-org)")
'';
}
];
}
];
};
};
description = ''
Templates configuration
Refer to the [Tuliprox documentation] for available attributes
[Tuliprox documentation]: https://github.com/euzu/tuliprox?tab=readme-ov-file#2-mappingyml
'';
};
};
config = lib.mkIf cfg.enable {
services.tuliprox.systemSettings = {
api = {
host = lib.mkDefault "127.0.0.1";
port = lib.mkDefault 8901;
web_root = lib.mkDefault "${cfg.package}/web";
};
working_dir = lib.mkDefault "\${env:STATE_DIRECTORY}/data";
backup_dir = lib.mkDefault "\${env:STATE_DIRECTORY}/backup";
custom_stream_response_path = lib.mkDefault "${cfg.package}/resources";
};
services.tuliprox.sourceSettings.sources = lib.mkDefault [ ];
services.tuliprox.apiProxySettings = {
server = lib.mkDefault [
{
name = "default";
protocol = "http";
host = cfg.systemSettings.api.host;
port = cfg.systemSettings.api.port;
timezone = if config.time.timeZone != null then config.time.timeZone else "Etc/UTC";
message = "Welcome to tuliprox";
}
];
user = lib.mkDefault [ ];
};
services.tuliprox.mappingSettings.mappings.mapping = lib.mkDefault [ ];
systemd.services.tuliprox = {
description = "Tuliprox server";
serviceConfig = {
ExecStart = utils.escapeSystemdExecArgs (
[
(lib.getExe cfg.package)
"--server"
"--config"
systemSettingsYaml
"--source"
sourceSettingsYaml
"--api-proxy"
apiProxySettingsYaml
"--mapping"
mappingSettingsYaml
]
++ cfg.extraArgs
);
Restart = "always";
DynamicUser = true;
StateDirectory = "tuliprox";
CapabilityBoundingSet = "";
LockPersonality = true;
MemoryDenyWriteExecute = true;
PrivateDevices = true;
PrivateUsers = true;
ProcSubset = "pid";
ProtectClock = true;
ProtectControlGroups = true;
ProtectHome = true;
ProtectHostname = true;
ProtectKernelLogs = true;
ProtectKernelModules = true;
ProtectKernelTunables = true;
ProtectProc = "invisible";
RestrictAddressFamilies = [
"AF_UNIX"
"AF_INET"
"AF_INET6"
];
RestrictNamespaces = true;
RestrictRealtime = true;
SystemCallArchitectures = "native";
SystemCallFilter = [
"@system-service"
"~@privileged"
"~@resources"
];
UMask = "0066";
};
wantedBy = [ "multi-user.target" ];
};
};
}
+1
View File
@@ -1582,6 +1582,7 @@ in
trilium-server = runTestOn [ "x86_64-linux" ] ./trilium-server.nix;
tsm-client-gui = runTest ./tsm-client-gui.nix;
ttyd = runTest ./web-servers/ttyd.nix;
tuliprox = runTest ./tuliprox.nix;
tuned = runTest ./tuned.nix;
tuptime = runTest ./tuptime.nix;
turbovnc-headless-server = runTest ./turbovnc-headless-server.nix;
+19
View File
@@ -0,0 +1,19 @@
{ lib, pkgs, ... }:
{
name = "tuliprox";
meta.maintainers = with lib.maintainers; [ nyanloutre ];
nodes.machine =
{ pkgs, ... }:
{
services.tuliprox = {
enable = true;
};
};
testScript = ''
machine.wait_for_unit("multi-user.target")
machine.wait_for_open_port(8901)
machine.succeed("curl -v -s http://127.0.0.1:8901/")
'';
}
+84
View File
@@ -0,0 +1,84 @@
{
lib,
fetchFromGitHub,
rustPlatform,
pkg-config,
openssl,
ffmpeg,
which,
rustc,
wasm-bindgen-cli_0_2_104,
trunk,
binaryen,
dart-sass,
nixosTests,
nix-update-script,
}:
rustPlatform.buildRustPackage rec {
pname = "tuliprox";
version = "3.2.0";
src = fetchFromGitHub {
owner = "euzu";
repo = "tuliprox";
tag = "v${version}";
hash = "sha256-G+bVKBAxviyJShq2BG4vjMiTzHhoYaiP6FXrSWeTvkU=";
};
nativeBuildInputs = [
pkg-config
ffmpeg
which
wasm-bindgen-cli_0_2_104
trunk
rustc.llvmPackages.lld
binaryen
dart-sass
];
# Needed to get openssl-sys to use pkg-config.
env = {
OPENSSL_NO_VENDOR = 1;
OPENSSL_LIB_DIR = "${lib.getLib openssl}/lib";
OPENSSL_DIR = "${lib.getDev openssl}";
};
cargoHash = "sha256-bDQ4pDDTINTgotTen1/SxOZBmkUmbmmwmR4/nSoSf/A=";
cargoBuildFlags = "--package tuliprox";
postBuild = ''
patchShebangs ./bin/build_resources.sh
./bin/build_resources.sh
pushd frontend
trunk build --offline --frozen --release
popd
'';
checkFlags = [
"--skip=processing::parser::xmltv::tests::normalize"
"--skip=processing::parser::xtream::tests::test_read_json_file_into_struct"
"--skip=repository::indexed_document::tests::test_read_xt"
];
postInstall = ''
cp -rf frontend/dist $out/web
mkdir -p $out/resources
cp -rf resources/*.ts $out/resources
'';
passthru = {
tests = { inherit (nixosTests) tuliprox; };
updateScript = nix-update-script { };
};
meta = {
description = "Flexible IPTV playlist processor & proxy in Rust";
homepage = "https://github.com/euzu/tuliprox";
changelog = "https://github.com/euzu/tuliprox/blob/${src.tag}/CHANGELOG.md";
mainProgram = "tuliprox";
license = with lib.licenses; [ mit ];
maintainers = with lib.maintainers; [ nyanloutre ];
};
}