Skip to content

Commit

Permalink
pinchflat: init at v2025.1.3
Browse files Browse the repository at this point in the history
  • Loading branch information
charludo committed Jan 11, 2025
1 parent b15506c commit 33e1793
Show file tree
Hide file tree
Showing 6 changed files with 1,239 additions and 0 deletions.
6 changes: 6 additions & 0 deletions maintainers/maintainer-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -3961,6 +3961,12 @@
githubId = 6608071;
name = "Charles Huyghues-Despointes";
};
charludo = {
email = "[email protected]";
github = "charludo";
githubId = 47758554;
name = "Charlotte Harludo";
};
chayleaf = {
email = "[email protected]";
github = "chayleaf";
Expand Down
2 changes: 2 additions & 0 deletions nixos/doc/manual/release-notes/rl-2505.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,8 @@

- [crab-hole](https://github.com/LuckyTurtleDev/crab-hole), a cross platform Pi-hole clone written in Rust using hickory-dns/trust-dns. Available as [services.crab-hole](#opt-services.crab-hole.enable).

- [Pinchflat](https://github.com/kieraneglin/pinchflat), a selfhosted YouTube media manager used to track channels and download videos on release. Available as [services.pinchflat](#opt-services.pinchflat.enable).

- [Amazon CloudWatch Agent](https://github.com/aws/amazon-cloudwatch-agent), the official telemetry collector for AWS CloudWatch and AWS X-Ray. Available as [services.amazon-cloudwatch-agent](options.html#opt-services.amazon-cloudwatch-agent.enable).

- [Bat](https://github.com/sharkdp/bat), a {manpage}`cat(1)` clone with wings. Available as [programs.bat](options.html#opt-programs.bat).
Expand Down
1 change: 1 addition & 0 deletions nixos/modules/module-list.nix
Original file line number Diff line number Diff line change
Expand Up @@ -835,6 +835,7 @@
./services/misc/parsoid.nix
./services/misc/persistent-evdev.nix
./services/misc/pghero.nix
./services/misc/pinchflat.nix
./services/misc/pinnwand.nix
./services/misc/plex.nix
./services/misc/plikd.nix
Expand Down
163 changes: 163 additions & 0 deletions nixos/modules/services/misc/pinchflat.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,163 @@
{
config,
pkgs,
lib,
...
}:

let
cfg = config.services.pinchflat;
inherit (lib)
mkEnableOption
mkPackageOption
mkOption
types
mkIf
getExe
literalExpression
optional
attrValues
mapAttrs
;

stateDir = "/var/lib/pinchflat";
in
{
options = {
services.pinchflat = {
enable = mkEnableOption "pinchflat";

mediaDir = mkOption {
type = types.path;
defaultText = "/var/lib/pinchflat/media";
default = "${stateDir}/media";
description = "The directory into which Pinchflat downloads videos.";
};

port = mkOption {
type = types.port;
default = 8945;
description = "Port on which the Pinchflat web interface is available.";
};

openFirewall = mkOption {
type = types.bool;
default = false;
description = "Open ports in the firewall for the Pinchflat web interface";
};

selfhosted = mkOption {
type = types.bool;
default = false;
description = "Use a weak secret. If true, you are not required to provide a {env}`SECRET_KEY_BASE` through the `secretsFile` option. Do not use this option in production!";
};

logLevel = mkOption {
type = types.enum [
"debug"
"info"
"warning"
"error"
];
default = "info";
description = "Log level for Pinchflat.";
};

extraConfig = mkOption {
type =
with types;
attrsOf (
nullOr (oneOf [
bool
int
str
])
);
default = { };
example = literalExpression ''
{
YT_DLP_WORKER_CONCURRENCY = 1;
}
'';
description = ''
The configuration of Pinchflat is handled through environment variables.
The available configuration options can be found in [the Pinchflat README](https://github.com/kieraneglin/pinchflat/README.md#environment-variables).
'';
};

secretsFile = mkOption {
type = with types; nullOr path;
default = null;
example = "/run/secrets/pinchflat";
description = ''
Secrets like {env}`SECRET_KEY_BASE` and {env}`BASIC_AUTH_PASSWORD`
should be passed to the service without adding them to the world-readable Nix store.
Note that either this file needs to be available on the host on which `pinchflat` is running,
or the option `selfhosted` must be `true`.
Further, {env}`SECRET_KEY_BASE` has a minimum length requirement of 64 bytes.
One way to generate such a secret is to use `openssl rand -hex 64`.
As an example, the contents of the file might look like this:
```
SECRET_KEY_BASE=...copy-paste a secret token here...
BASIC_AUTH_USERNAME=...basic auth username...
BASIC_AUTH_PASSWORD=...basic auth password...
```
'';
};

package = mkPackageOption pkgs "pinchflat" { };
};
};

config = mkIf cfg.enable {
assertions = [
{
assertion = cfg.selfhosted || !builtins.isNull cfg.secretsFile;
message = "Either `selfhosted` must be true, or a `secretsFile` must be configured.";
}
];

systemd.services.pinchflat = {
description = "pinchflat";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
path = [
pkgs.apprise
pkgs.yt-dlp
];

serviceConfig = {
Type = "simple";
DynamicUser = true;
StateDirectory = baseNameOf stateDir;
Environment =
[
"PORT=${builtins.toString cfg.port}"
"TZ=${config.time.timeZone}"
"MEDIA_PATH=${cfg.mediaDir}"
"CONFIG_PATH=${stateDir}"
"DATABASE_PATH=${stateDir}/db/pinchflat.db"
"LOG_PATH=${stateDir}/logs/pinchflat.log"
"METADATA_PATH=${stateDir}/metadata"
"EXTRAS_PATH=${stateDir}/extras"
"TMPFILE_PATH=${stateDir}/tmp"
"TZ_DATA_PATH=${stateDir}/extras/elixir_tz_data"
"LOG_LEVEL=${cfg.logLevel}"
"PHX_SERVER=true"
]
++ optional cfg.selfhosted [ "RUN_CONTEXT=selfhosted" ]
++ attrValues (mapAttrs (name: value: name + "=" + builtins.toString value) cfg.extraConfig);
EnvironmentFile = optional (cfg.secretsFile != null) cfg.secretsFile;
ExecStartPre = "${cfg.package}/bin/migrate";
ExecStart = "${getExe cfg.package} start";
Restart = "on-failure";
};
};

networking.firewall = mkIf cfg.openFirewall {
allowedTCPPorts = [ cfg.port ];
};
};
}
Loading

0 comments on commit 33e1793

Please sign in to comment.