nix-files/modules/data/feeds/default.nix

59 lines
2.2 KiB
Nix

{ lib, ... }:
let
inherit (builtins) concatLists concatStringsSep foldl' fromJSON map readDir readFile;
inherit (lib) init mapAttrsToList removePrefix removeSuffix splitString;
inherit (lib.attrsets) recursiveUpdate setAttrByPath;
inherit (lib.filesystem) listFilesRecursive;
# given a path to a .json file relative to sources, construct the best feed object we can.
# the .json file could be empty, in which case we make assumptions about the feed based
# on its fs path.
# Type: feedFromSourcePath :: String -> { path = [String]; value = feed; }
feedFromSourcePath = json-path:
let
canonical-name = removeSuffix "/default" (lib.removeSuffix ".json" json-path);
default-url = "https://${canonical-name}";
attr-path = splitString "/" canonical-name;
feed-details = { url = default-url; } // (tryImportJson (./sources/${json-path}));
in { path = attr-path; value = mkFeed feed-details; };
# TODO: for now, feeds are just ordinary Attrs.
# in the future, we'd like to set them up with an update script.
mkFeed = { url, ... }@details: details;
# return an AttrSet representing the json at the provided path,
# or {} if the path is empty.
tryImportJson = path:
let
as-str = readFile path;
in
if as-str == "" then
{}
else
fromJSON as-str;
sources = enumerateFilePaths ./sources;
# like `lib.listFilesRecursive` but does not mangle paths.
# Type: enumerateFilePaths :: path -> [String]
enumerateFilePaths = base:
concatLists (
mapAttrsToList
(name: type:
if type == "directory" then
# enumerate this directory and then prefix each result with the directory's name
map (e: "${name}/${e}") (enumerateFilePaths (base + "/${name}"))
else
[ name ]
)
(readDir base)
);
# like listToAttrs, except takes { path, value } pairs instead of { name, value } pairs.
# Type: listToAttrsByPath :: [{ path = [String]; value = Any; }] -> Attrs
listToAttrsByPath = items:
foldl' (acc: { path, value }: recursiveUpdate acc (setAttrByPath path value)) {} items;
in
listToAttrsByPath (map feedFromSourcePath sources)