440 lines
13 KiB
Nix
440 lines
13 KiB
Nix
{
|
|
config,
|
|
lib,
|
|
namespace,
|
|
...
|
|
}:
|
|
with lib;
|
|
let
|
|
name = "glance";
|
|
cfg = config.${namespace}.services.${name};
|
|
|
|
hostedServiceSites =
|
|
let
|
|
servicesCfg = config.${namespace}.services;
|
|
serviceNames = attrNames servicesCfg;
|
|
in
|
|
concatMap (
|
|
serviceName:
|
|
let
|
|
serviceCfg = servicesCfg.${serviceName};
|
|
hosted = serviceCfg.hostedService or null;
|
|
in
|
|
if hosted != null && hosted.enable then
|
|
[
|
|
(
|
|
{
|
|
inherit (hosted) title url icon;
|
|
}
|
|
// optionalAttrs hosted.basicAuth {
|
|
basic-auth = {
|
|
username = "\${ARR_USER}";
|
|
password = "\${ARR_PASS}";
|
|
};
|
|
}
|
|
)
|
|
]
|
|
else
|
|
[ ]
|
|
) serviceNames;
|
|
|
|
hostedServicesByGroup = groupBy (svc: svc.hostedService.group) (
|
|
filter (svc: svc.hostedService != null && svc.hostedService.enable) (
|
|
map (
|
|
serviceName:
|
|
let
|
|
serviceCfg = config.${namespace}.services.${serviceName};
|
|
in
|
|
{
|
|
hostedService = serviceCfg.hostedService or null;
|
|
}
|
|
) (attrNames config.${namespace}.services)
|
|
)
|
|
);
|
|
|
|
makeMonitorWidget = title: sites: {
|
|
type = "monitor";
|
|
cache = "1m";
|
|
inherit title;
|
|
inherit sites;
|
|
};
|
|
|
|
glanceConfig = lib.${namespace}.mkModule {
|
|
inherit config name;
|
|
description = "glance";
|
|
options = {
|
|
nasPoolPath = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = cfg.dataDir;
|
|
description = "Path to the NAS pool mount to display in server-stats.";
|
|
};
|
|
|
|
enableHostedServices = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = true;
|
|
description = "Auto-discover services with hostedService.enable and add them to the monitor widget";
|
|
};
|
|
|
|
hostedServiceGroups = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = false;
|
|
description = "Create separate monitor widgets for each hostedService group instead of one combined widget";
|
|
};
|
|
|
|
extraSites = lib.mkOption {
|
|
type = lib.types.listOf (
|
|
lib.types.submodule {
|
|
options = {
|
|
title = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Display title";
|
|
};
|
|
url = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Service URL";
|
|
};
|
|
icon = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "si:glance";
|
|
description = "Icon identifier (e.g. si:servicename)";
|
|
};
|
|
allow-insecure = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = false;
|
|
description = "Allow insecure connections";
|
|
};
|
|
basic-auth = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = false;
|
|
description = "Require basic auth (uses ARR credentials)";
|
|
};
|
|
};
|
|
}
|
|
);
|
|
default = [ ];
|
|
description = "Extra sites to display in the monitor widget";
|
|
};
|
|
|
|
weather = lib.mkOption {
|
|
type = lib.types.submodule {
|
|
options = {
|
|
enable = lib.mkOption {
|
|
type = lib.types.bool;
|
|
default = true;
|
|
description = "Enable weather widget";
|
|
};
|
|
location = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "Saint Paul, Minnesota, United States";
|
|
description = "Weather location";
|
|
};
|
|
units = lib.mkOption {
|
|
type = lib.types.enum [
|
|
"imperial"
|
|
"metric"
|
|
];
|
|
default = "imperial";
|
|
description = "Temperature units";
|
|
};
|
|
hour-format = lib.mkOption {
|
|
type = lib.types.enum [
|
|
"12h"
|
|
"24h"
|
|
];
|
|
default = "12h";
|
|
description = "Hour format";
|
|
};
|
|
};
|
|
};
|
|
default = { };
|
|
description = "Weather widget settings";
|
|
};
|
|
|
|
bookmarks = lib.mkOption {
|
|
type = lib.types.listOf (
|
|
lib.types.submodule {
|
|
options = {
|
|
title = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Group title";
|
|
};
|
|
links = lib.mkOption {
|
|
type = lib.types.listOf (
|
|
lib.types.submodule {
|
|
options = {
|
|
title = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Link title";
|
|
};
|
|
url = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Link URL";
|
|
};
|
|
};
|
|
}
|
|
);
|
|
description = "List of links";
|
|
};
|
|
};
|
|
}
|
|
);
|
|
default = [
|
|
{
|
|
title = "General";
|
|
links = [
|
|
{
|
|
title = "Gmail";
|
|
url = "https://mail.google.com/mail/u/0/";
|
|
}
|
|
{
|
|
title = "Proton Mail";
|
|
url = "https://mail.proton.me/u/0/inbox";
|
|
}
|
|
{
|
|
title = "MyNixOS";
|
|
url = "https://www.mynixos.com/";
|
|
}
|
|
{
|
|
title = "Github";
|
|
url = "https://github.com/";
|
|
}
|
|
];
|
|
}
|
|
{
|
|
title = "Entertainment";
|
|
links = [
|
|
{
|
|
title = "YouTube";
|
|
url = "https://www.youtube.com/";
|
|
}
|
|
{
|
|
title = "Prime Video";
|
|
url = "https://www.primevideo.com/";
|
|
}
|
|
{
|
|
title = "Disney+";
|
|
url = "https://www.disneyplus.com/";
|
|
}
|
|
];
|
|
}
|
|
{
|
|
title = "Social";
|
|
links = [
|
|
{
|
|
title = "Reddit";
|
|
url = "https://www.reddit.com/";
|
|
}
|
|
{
|
|
title = "Twitter";
|
|
url = "https://twitter.com/";
|
|
}
|
|
{
|
|
title = "Instagram";
|
|
url = "https://www.instagram.com/";
|
|
}
|
|
];
|
|
}
|
|
];
|
|
description = "Bookmark groups";
|
|
};
|
|
|
|
reddit = lib.mkOption {
|
|
type = lib.types.listOf lib.types.str;
|
|
default = [
|
|
"hockey"
|
|
"formula1"
|
|
];
|
|
description = "Subreddits to show in Reddit widgets";
|
|
};
|
|
|
|
search = lib.mkOption {
|
|
type = lib.types.listOf (
|
|
lib.types.submodule {
|
|
options = {
|
|
title = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Search engine title";
|
|
};
|
|
shortcut = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Bang shortcut (e.g. !yt)";
|
|
};
|
|
url = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Search URL with {QUERY} placeholder";
|
|
};
|
|
};
|
|
}
|
|
);
|
|
default = [
|
|
{
|
|
title = "YouTube";
|
|
shortcut = "!yt";
|
|
url = "https://www.youtube.com/results?search_query={QUERY}";
|
|
}
|
|
];
|
|
description = "Custom search engine bangs";
|
|
};
|
|
|
|
servers = lib.mkOption {
|
|
type = lib.types.listOf (
|
|
lib.types.submodule {
|
|
options = {
|
|
name = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Server name";
|
|
};
|
|
cpu-temp-sensor = lib.mkOption {
|
|
type = lib.types.str;
|
|
default = "";
|
|
description = "CPU temp sensor path";
|
|
};
|
|
mountpoints = lib.mkOption {
|
|
type = lib.types.attrsOf (
|
|
lib.types.submodule {
|
|
options = {
|
|
name = lib.mkOption {
|
|
type = lib.types.str;
|
|
description = "Display name for mountpoint";
|
|
};
|
|
};
|
|
}
|
|
);
|
|
description = "Mountpoints to display";
|
|
};
|
|
};
|
|
}
|
|
);
|
|
default = [
|
|
{
|
|
name = "Jallen-NAS";
|
|
cpu-temp-sensor = "/sys/devices/pci0000:00/0000:00:08.1/0000:cd:00.0/hwmon/hwmon*/temp1_input";
|
|
mountpoints = {
|
|
"/home" = {
|
|
name = "Home";
|
|
};
|
|
"${cfg.nasPoolPath}" = {
|
|
name = "nas_pool";
|
|
};
|
|
};
|
|
}
|
|
];
|
|
description = "Servers for server-stats widget";
|
|
};
|
|
};
|
|
moduleConfig = {
|
|
services.glance = {
|
|
enable = true;
|
|
openFirewall = true;
|
|
environmentFile = config.sops.templates."glance.env".path;
|
|
settings = {
|
|
server = {
|
|
host = "0.0.0.0";
|
|
inherit (cfg) port;
|
|
};
|
|
pages = [
|
|
{
|
|
name = "Startpage";
|
|
width = "default";
|
|
hide-desktop-navigation = true;
|
|
center-vertically = true;
|
|
columns = [
|
|
{
|
|
size = "small";
|
|
widgets = [
|
|
{
|
|
type = "calendar";
|
|
first-day-of-week = "sunday";
|
|
}
|
|
]
|
|
++ lib.optional cfg.weather.enable {
|
|
type = "weather";
|
|
units = cfg.weather.units;
|
|
hour-format = cfg.weather.hour-format;
|
|
location = cfg.weather.location;
|
|
}
|
|
++ lib.optional (cfg.servers != [ ]) {
|
|
type = "server-stats";
|
|
servers = cfg.servers;
|
|
};
|
|
}
|
|
{
|
|
size = "full";
|
|
widgets = [
|
|
{
|
|
type = "search";
|
|
autofocus = true;
|
|
search-engine = "google";
|
|
bangs = cfg.search;
|
|
}
|
|
]
|
|
++ lib.optionals cfg.hostedServiceGroups (
|
|
map (
|
|
groupName:
|
|
makeMonitorWidget groupName (
|
|
map (svc: {
|
|
inherit (svc.hostedService) title url icon;
|
|
}) (hostedServicesByGroup.${groupName} or [ ])
|
|
)
|
|
) (attrNames hostedServicesByGroup)
|
|
)
|
|
++ lib.optionals (!cfg.hostedServiceGroups && cfg.enableHostedServices) [
|
|
(makeMonitorWidget "Services" hostedServiceSites)
|
|
]
|
|
++ lib.optionals (cfg.extraSites != [ ]) (
|
|
map (site: {
|
|
type = "monitor";
|
|
cache = "1m";
|
|
inherit (site) title;
|
|
sites = [
|
|
(
|
|
{
|
|
inherit (site) title url icon;
|
|
}
|
|
// optionalAttrs site.allow-insecure { allow-insecure = true; }
|
|
)
|
|
];
|
|
}) cfg.extraSites
|
|
)
|
|
++ lib.optional (cfg.bookmarks != [ ]) {
|
|
type = "bookmarks";
|
|
groups = cfg.bookmarks;
|
|
}
|
|
++ lib.optionals (cfg.reddit != [ ]) (
|
|
map (subreddit: {
|
|
type = "reddit";
|
|
inherit subreddit;
|
|
}) cfg.reddit
|
|
);
|
|
}
|
|
];
|
|
}
|
|
];
|
|
};
|
|
};
|
|
};
|
|
};
|
|
in
|
|
{
|
|
imports = [
|
|
glanceConfig
|
|
|
|
{
|
|
config = lib.mkIf cfg.enable (
|
|
lib.${namespace}.mkSopsEnvFile {
|
|
name = "glance.env";
|
|
restartUnit = "glance.service";
|
|
secrets = {
|
|
"jallen-nas/glance/arr-username" = { };
|
|
"jallen-nas/glance/arr-password" = { };
|
|
};
|
|
content = ''
|
|
ARR_USER=${config.sops.placeholder."jallen-nas/glance/arr-username"}
|
|
ARR_PASS=${config.sops.placeholder."jallen-nas/glance/arr-password"}
|
|
'';
|
|
}
|
|
);
|
|
}
|
|
];
|
|
}
|