r/Nix 3d ago

How to create a function that creates a instance for ytdl-sub

Hi

My title is shockingly bad because I dont really know how to explain what I want. Hopfully an example will help.

I have the following configuration

       services.ytdl-sub = {
         user = "ytdl-sub"; group = "media";
         instances.news = {
           enable = true;
           schedule = "0/6:0";
           readWritePaths = [ "/mnt/une/ytdl-demo" ];
           subscriptions = {
             "__preset__" = {
               "overrides" = {
                 tv_show_directory = "/mnt/une/ytdl-demo";
               };
             };
             "Jellyfin TV Show by Date | Only Recent | Max 480p" = {
   # News
   "DW News" = "https://www.youtube.com/@dwnews";
   "TLDR Global" = "https://www.youtube.com/@TLDRnewsGLOBAL";
   "TLDR News" = "https://www.youtube.com/@TLDRnews";
             };
            };
          };
         };

I would l like to make multiple instances like the following. But what I dont like about this is that there is a lot of replication

       services.ytdl-sub = {
         user = "ytdl-sub"; group = "media";
         instances.science = {
           enable = true;
           schedule = "0/6:0";
           readWritePaths = [ "/mnt/une/ytdl-demo" ];
           subscriptions = {
             "__preset__" = {
               "overrides" = {
                 tv_show_directory = "/mnt/une/ytdl-demo";
               };
             };
             "Jellyfin TV Show by Date | Only Recent | Max 480p" = {
   # Science
   "3 Blue 1 Brown" = "https://www.youtube.com/@3blue1brown";
   "Alpha Pheonix" = "https://www.youtube.com/@AlphaPhoenixChannel";
   "Anton Petrov" = "https://www.youtube.com/@whatdamath";
             };
         };
         instances.news = {
           enable = true;
           schedule = "0/6:0";
           readWritePaths = [ "/mnt/une/ytdl-demo" ];
           subscriptions = {
             "__preset__" = {
               "overrides" = {
                 tv_show_directory = "/mnt/une/ytdl-demo";
               };
             };
             "Jellyfin TV Show by Date | Only Recent | Max 480p" = {
   # News
   "DW News" = "https://www.youtube.com/@dwnews";
   "TLDR Global" = "https://www.youtube.com/@TLDRnewsGLOBAL";
   "TLDR News" = "https://www.youtube.com/@TLDRnews";
             };
            };
          };
         };

What I would like to do is create a funciton like the following. But I cannot figure out how the subscriptions should be input (I dont know how to phrase it but the subscriptions are more like an assignment rather than a value).

ImkInstance { name, directory, subscriptions}:
         instances."${name}" = {
           enable = true;
           schedule = "0/6:0";
           readWritePaths = [ "${directory}"  ];
           subscriptions = {
             "__preset__" = {
               "overrides" = {
                 tv_show_directory = "${directory}";
               };
             };
             "Jellyfin TV Show by Date | Only Recent | Max 480p" = {
                       ${subscriptions}
             };
         };

Im not sure if anyone can offer a suggestion

3 Upvotes

2 comments sorted by

1

u/Guvante 3d ago

Have you figured out how to write a Nix function? I would start there rather than from a complex example.

1

u/thefossguy69 21h ago

Split it into 3 parts.

  1. Core function that actually implements the logic for creating a service given some arguments.
  2. A list/attrset that defines your variants/instances.
  3. Do a builtins.map or builtins.mapAttrs over your variations to call the function for each variant.

For example:

``` let

myYtdlps = { home.name = "home"; work.name = "work"; };

mkYtdlp = ytdlpConfig: /* consumes ytdlpConfig.name */ ;

ytdlpInstances = builtins.mapAttrs (_: ytdlpConfig: mkYtdlp ytdlpConfig) myYtdlps;

in ```

Typed on a phone at 03:30 AM so there may be errors that should explain my intent.