Compare commits

...

9 commits

Author SHA1 Message Date
5b20695207
flake.lock: Update
Flake lock file updates:

• Updated input 'fetch-rs':
    'github:Gerg-L/fetch-rs/b9b2e406412a6f416d6ac2c6fab24ac79cb78d15?narHash=sha256-vEomFIFl2nXUJQC0fuSKexUYqufhebbkyx%2BhF2l1bX8%3D' (2025-01-22)
  → 'github:Gerg-L/fetch-rs/d4a675837ac40c54cf1b3987c783645376d6cbbb?narHash=sha256-GUItxBNz/VtVAjPnltF0RYCDChIhfn0YV5T/GSG9jFI%3D' (2025-03-12)
2025-03-13 20:22:47 -04:00
2415a07922
ddns: remove wantedBy 2025-03-13 20:22:32 -04:00
0dedea7fae
flake.lock: Update
Flake lock file updates:

• Updated input 'nvim-flake':
    'github:Gerg-L/nvim-flake/cf2223a7d041af388ad8e05cea5265c8e04c84d8?narHash=sha256-z0enmKFtlFiJXeXMmiWRtRMSvbfVyICmTmDDdMHdkL0%3D' (2025-03-09)
  → 'github:Gerg-L/nvim-flake/ad53aad5d8fe0c5215a703dbb2df5b2704f08a13?narHash=sha256-W66Plcq5rOWSOa64VySwCKfOuv3ottMuFIk37Eorj%2BQ%3D' (2025-03-14)
2025-03-13 20:08:38 -04:00
b92568fbde
lib: add overlay 2025-03-13 19:38:12 -04:00
8fcc7d718e
xorg cleanup 2025-03-13 19:38:12 -04:00
518ab13797
better services 2025-03-13 19:38:12 -04:00
29b35ab058
pipe operators 2025-03-13 19:38:12 -04:00
4f0a7c169c
vocard: use nix for configuration 2025-03-13 19:38:12 -04:00
bf8e99ce0e
plymouth simpledrm 2025-03-13 19:38:12 -04:00
25 changed files with 651 additions and 619 deletions

12
flake.lock generated
View file

@ -42,11 +42,11 @@
]
},
"locked": {
"lastModified": 1737589030,
"narHash": "sha256-vEomFIFl2nXUJQC0fuSKexUYqufhebbkyx+hF2l1bX8=",
"lastModified": 1741820453,
"narHash": "sha256-GUItxBNz/VtVAjPnltF0RYCDChIhfn0YV5T/GSG9jFI=",
"owner": "Gerg-L",
"repo": "fetch-rs",
"rev": "b9b2e406412a6f416d6ac2c6fab24ac79cb78d15",
"rev": "d4a675837ac40c54cf1b3987c783645376d6cbbb",
"type": "github"
},
"original": {
@ -631,11 +631,11 @@
"systems": "systems"
},
"locked": {
"lastModified": 1741483537,
"narHash": "sha256-z0enmKFtlFiJXeXMmiWRtRMSvbfVyICmTmDDdMHdkL0=",
"lastModified": 1741910893,
"narHash": "sha256-W66Plcq5rOWSOa64VySwCKfOuv3ottMuFIk37Eorj+Q=",
"owner": "Gerg-L",
"repo": "nvim-flake",
"rev": "cf2223a7d041af388ad8e05cea5265c8e04c84d8",
"rev": "ad53aad5d8fe0c5215a703dbb2df5b2704f08a13",
"type": "github"
},
"original": {

View file

@ -1,141 +1,8 @@
{
unstable,
self,
...
}@inputs:
let
inherit (unstable) lib;
in
lib.fix (myLib: {
wrench = lib.flip lib.pipe;
needsSystem = lib.flip builtins.elem [
"apps"
"checks"
"defaultPackage"
"devShell"
"devShells"
"formatter"
"legacyPackages"
"packages"
];
constructInputs' =
system:
myLib.wrench [
(lib.filterAttrs (_: lib.isType "flake"))
(lib.mapAttrs (
_: lib.mapAttrs (name: value: if myLib.needsSystem name then value.${system} else value)
))
];
listNixFilesRecursive = myLib.wrench [
builtins.unsafeDiscardStringContext
lib.filesystem.listFilesRecursive
(builtins.filter (x: !lib.hasPrefix "_" (builtins.baseNameOf x) && lib.hasSuffix ".nix" x))
];
addSchizophreniaToModule =
x:
let
# the imported module
imported = import x;
in
/*
If the module isn't a function then
it doesn't need arguments and error
message locations will function correctly
*/
if !lib.isFunction imported then
x
else
let
# all arguments defined in the module
funcArgs = lib.functionArgs imported;
/*
The names of all arguments which will be
available to be inserted into the module arguments
*/
argNames = builtins.attrNames inputs ++ [
"inputs"
"inputs'"
"self'"
"_dir"
];
/*
arguments to be passed minus
per system attributes
for example flake-parts-esque inputs'
*/
argsPre = {
inherit inputs self;
/*
_dir is the "self" derived
path to the directory containing the module
*/
_dir = builtins.dirOf x;
};
/*
arguments which will be inserted
set to the before per-system values
*/
providedArgs = lib.pipe funcArgs [
(lib.filterAttrs (n: _: builtins.elem n argNames))
(lib.mapAttrs (n: _: argsPre.${n} or { }))
];
/*
arguments which the module system
not provided here. either to be
provided by the module system or invalid
*/
neededArgs = lib.filterAttrs (n: _: !builtins.elem n argNames) funcArgs;
in
{
__functionArgs = neededArgs // {
/*
always require pkgs to be passed
to derive system from pkgs.stdenv.system
*/
pkgs = false;
};
__functor =
/*
args is specialArgs + _module.args which are needed
and always pkgs
*/
_: args:
imported (
/*
take module system provided arguments
filter them so only the required ones are passed
*/
(lib.filterAttrs (n: _: neededArgs ? ${n}) args)
# add needed arguments
// (
providedArgs
# add system dependent arguments
// (
let
inputs' = myLib.constructInputs' args.pkgs.stdenv.system inputs;
actuallyAllArgs = inputs' // {
inherit inputs';
self' = inputs'.self;
inherit (inputs) self;
};
in
lib.filterAttrs (n: _: providedArgs ? ${n}) actuallyAllArgs
)
)
)
# add _file to the final module attribute set
// {
_file = x;
};
};
})
lib.fix (self: (import ./overlay.nix inputs self lib))

137
lib/overlay.nix Normal file
View file

@ -0,0 +1,137 @@
{ self, ... }@inputs:
myLib: lib: {
overlay = import ./overlay.nix inputs;
wrench = lib.flip lib.pipe;
needsSystem = lib.flip builtins.elem [
"apps"
"checks"
"defaultPackage"
"devShell"
"devShells"
"formatter"
"legacyPackages"
"packages"
];
constructInputs' =
system:
myLib.wrench [
(lib.filterAttrs (_: lib.isType "flake"))
(lib.mapAttrs (
_: lib.mapAttrs (name: value: if myLib.needsSystem name then value.${system} else value)
))
];
listNixFilesRecursive = myLib.wrench [
builtins.unsafeDiscardStringContext
lib.filesystem.listFilesRecursive
(builtins.filter (x: !lib.hasPrefix "_" (builtins.baseNameOf x) && lib.hasSuffix ".nix" x))
];
addSchizophreniaToModule =
x:
let
# the imported module
imported = import x;
in
/*
If the module isn't a function then
it doesn't need arguments and error
message locations will function correctly
*/
if !lib.isFunction imported then
x
else
let
# all arguments defined in the module
funcArgs = lib.functionArgs imported;
/*
The names of all arguments which will be
available to be inserted into the module arguments
*/
argNames = builtins.attrNames inputs ++ [
"inputs"
"inputs'"
"self'"
"_dir"
];
/*
arguments to be passed minus
per system attributes
for example flake-parts-esque inputs'
*/
argsPre = {
inherit inputs self;
/*
_dir is the "self" derived
path to the directory containing the module
*/
_dir = builtins.dirOf x;
};
/*
arguments which will be inserted
set to the before per-system values
*/
providedArgs = lib.pipe funcArgs [
(lib.filterAttrs (n: _: builtins.elem n argNames))
(lib.mapAttrs (n: _: argsPre.${n} or { }))
];
/*
arguments which the module system
not provided here. either to be
provided by the module system or invalid
*/
neededArgs = lib.filterAttrs (n: _: !builtins.elem n argNames) funcArgs;
in
{
__functionArgs = neededArgs // {
/*
always require pkgs to be passed
to derive system from pkgs.stdenv.system
*/
pkgs = false;
};
__functor =
/*
args is specialArgs + _module.args which are needed
and always pkgs
*/
_: args:
imported (
/*
take module system provided arguments
filter them so only the required ones are passed
*/
(lib.filterAttrs (n: _: neededArgs ? ${n}) args)
# add needed arguments
// (
providedArgs
# add system dependent arguments
// (
let
inputs' = myLib.constructInputs' args.pkgs.stdenv.system inputs;
actuallyAllArgs = inputs' // {
inherit inputs';
self' = inputs'.self;
inherit (inputs) self;
};
in
lib.filterAttrs (n: _: providedArgs ? ${n}) actuallyAllArgs
)
)
)
# add _file to the final module attribute set
// {
_file = x;
};
};
}

View file

@ -9,11 +9,7 @@
{
local = {
DE.dwm.enable = true;
DM = {
lightdm.enable = true;
autoLogin = true;
loginUser = "gerg";
};
DM.lightdm.enable = true;
theming = {
enable = true;
kmscon.enable = true;
@ -114,7 +110,10 @@
'';
};
services.libinput.mouse.accelProfile = "flat";
services.displayManager.autoLogin = {
enable = true;
user = "gerg";
};
programs = {
steam.enable = true;

View file

@ -1,7 +1,10 @@
ferretdb: ENC[AES256_GCM,data:T+aeEtgiM4D+a7MOumE69UNMFjKYKASexSl5/r2HC2fSg93qlISwXRPuSXp6RidyWQE/HJWh3RdPzkbIkBtTmcyxF78gk/LlHsMbrCdSBHF9/hPd4N1AuKquZi8PvyDE6e0RjmUjZxn1PkzDdqWB7bWtYLFyZO7T8WaReouyZObFCG1hI00oT/s=,iv:6xwdMS/JPzVThT3rJmF7/MPs6oEoUwdwYhvyGC1mCrQ=,tag:wxBfckBmo+JM6me+PKcjfw==,type:str]
forgejo: ENC[AES256_GCM,data:gNpOxeXlkYIqIFTqQvFg3pr/b1P5CEVbKDDXhmNnsp6PpdLDKjdRsMobEAOHsSuqdRUpuRsLolAlMUayHyQZ5pLtATXhxLN9TZtucn52eKqVdYx4spbSbbPdHHRznEze55MZuNmMPH9Y3tk+uzIQgzOpHohRs8+/lI3dS8F2dfqg,iv:vIGaWyDRFoR5csdIwsLoHyr3LmA7qyOGshivdvYFy5c=,tag:hif0XGaLQRzhDFVDQLTDBQ==,type:str]
immich: ENC[AES256_GCM,data:P5sMIZ0qaXDvmJ9h1pm+w53FtjMFZcaHXFCqpqldEZ9umVRqidaie5C2c/5SMPpiNWxpFMksvzfA8CQrZVgFEo7kqbg/xU4KeZMEhAqC8tWku0Zi3c452479PARzRvN/e1v24KSzFA5X0zztDNRxMFpjIAURNhQ7ZxKaP/ItP/MW9rzukP3Ow5homThawjk=,iv:dvTLTyh1Cbcmmcq87yvGDffe43Q/Grp7lz36zI5Yd1A=,tag:fLgVTUyQqULiodM4MVfAlQ==,type:str]
cloudflare: ENC[AES256_GCM,data:RZ+Smjn1nvnkxYAF56fEcBsFvO3YY+FWJ8wb0c72sxQleRjy9tVp7yDr9gRfUg3G,iv:mGaFxKFLrIouNhyqq/nBKaKub1WfekcCeHVLASQpBCs=,tag:xKl5EHR9g7d4pJkt49BLyw==,type:str]
reboot_token: ENC[AES256_GCM,data:/3QP30OUZsFaagj9Ljde1jz5nxZA6jp6/B6pmlponepRy3uZJ2jlaYQ3EBDiv5L413ecfWePAeWlX07eZ08JIRdoO5Ky52LM1+nPHMJFXzQ0h2onz4RVQAM=,iv:qiRk93LM7+3QmW27ItoWYGo7PLlu/hpprcPdnOaCBdw=,tag:X9kEov2FOrsIqkkStLegPw==,type:str]
searxngenv: ENC[AES256_GCM,data:HtH4KxXWoQEJp88Bgfhfj5Y4Up+inHu8mnVtay64XvCRpVKHF/kceC3XwT9C3IdXpQ==,iv:iXK8hOFoEnM5wFUZhC8IOdHzPhwPDHtTL8MmS5FSlns=,tag:TZHTB7ia5Qq2f2fETJOpEA==,type:str]
minifluxenv: ENC[AES256_GCM,data:wgz6sxSbbjXrgBAak0Q0TlvG78+JHPpiPtcbqGo9HpSF3qY78edECCDB3qqIaynxdhI4,iv:mbsr+OG8fE5MggmC+TNkLmhhDNGvJo+uelNRo/rMLoo=,tag:xN+FbNHZIVCruQh23aMt5g==,type:str]
minifluxenv: ENC[AES256_GCM,data:xn1x68dE0+/wP627w7zbm+lCvOKfKkPahjlLN+4zg/zoTGbIrstb40HFLTt8opCMgW3OmCPIY45DjT49W29m8SipJwOjWvqbm5iGhI3KYgE/jzpjLnFiNLdigGeZ0aBf5OiN/ef82B+qkjlOcO3x0CWFSONLRsDqa0KJR/eHWFCsqdxJxUd9KpJ47TiPb4y7mvnfJebrg3IPxxABrImeg2d5a2RjDIueFdWyJLJol9JTJDPpTLFm0OEG6Xbr2G2sQQ==,iv:mXdcFtbLGTu3aOCJ/m/axA9bnHNqzPsQFuLv5Bj1Dkw=,tag:255hftEAi2CPsr5gwXs1zQ==,type:str]
gerg: ENC[AES256_GCM,data:iSwWGIIxQenCPMd/Tith/eagjVINn0mgrO99IG85cP4UXtut6GF2R57XDMeD7SU18vW1ULod/lYuTo0SmmrkmX+wlDWgm4cODw==,iv:fHTcn4ZmjSqLC8jQkuualRbp+RwvgblS1ic6WPb2WEY=,tag:rkDuXhvleKekv3bVpdNNuw==,type:str]
store_key: ENC[AES256_GCM,data:2XioKwoH0V5QuedXl4w2IFrT2qOQWF0kbchYTMhyL9BaUqYHhXQi4buvKUVbBQ8AnzD1GJT3ZRy1S13CxEkdQvXE0IY0iX5nkTJtI3VgpiF64wfvZqcLQGaaNTCg+AEDP304KtIZZiao,iv:PV0bORWHoRDM8HvFwOI2sl7QjfD9G0VXSZ9RrPBUsyM=,tag:caVnOow466eBT/5bqYU0Iw==,type:str]
github_token: ENC[AES256_GCM,data:LijyCmMkfaCmh3rVKB96GHd7eM5Qbj9Jea1UZbQGgf67rof1uS+XML+3hmC6lOf6iOeJQtg12fC3ODHnzGuiC+dd1VbIkL5xRR7VBpFF2g6q5ixz9On/IRP74lX7SexCbcOx6YHi6eU6FX6fXe8wWhM87RYZcuiaEw==,iv:GWpI5Q2svJCz28wPVwTPq/+aLN7bWFz4gHNm3Qe6YFI=,tag:1KO9shVI0m2DSomDAuGnsQ==,type:str]
@ -22,8 +25,8 @@ sops:
dGhDRXRTWE9xSGtxQU80RVpuL1A5MkEKxAxC/wDkq+6hM8eXkWd/RBDNIUtGYnPy
MvVxB6dkj+S11oRcMpdFqiM9jSzz/gYecB2tfuDgj+UX/VAzSkvPxA==
-----END AGE ENCRYPTED FILE-----
lastmodified: "2025-02-26T23:23:36Z"
mac: ENC[AES256_GCM,data:rUuzMNzXf2rgmT7t4eNXnVDtA4izwbc+8wvMztu5gvymJNBGf2B+uvFzEZMqMA+gmdqwX4B51K2oTYe7GU3EAgjp+7709hy4Dzs0vILebJn6ijO3AVHLEWLE7ia0cao6wAzKv6qtlyvAb1TvyTgtJpM+LCsuOkEItPJxoEDGlzc=,iv:rYlkNXaz/mk7WBYm27y/+eqJAThZ/pcjW6bMuTjTIZ4=,tag:end6/klu3sW9PuTIbWxZmw==,type:str]
lastmodified: "2025-03-06T03:09:11Z"
mac: ENC[AES256_GCM,data:3EeCTjNO74bwoa9mi2Da5jigmjwQC+IZO9eJS8V5ujuIz2suB1Q9xl7AUBk8JT5oqCvuVJZ4QuOjtSUp00h2f4cvuq0/VQWurb7RBDG956iT0v6Js+3s4sgZ6mTaD0W3IXYpQkoCLKA0EdfZpqayBAK8ToUYCJhCaNBLl7eUZBw=,iv:heJUcxMbJCmEq14woFFXGEfx2xlID0ZeDxtBK8kXWOE=,tag:jNahdAVH9IoIs63H3yW0AA==,type:str]
pgp: []
unencrypted_suffix: _unencrypted
version: 3.9.4

View file

@ -10,7 +10,6 @@
reloadIfChanged = false;
restartIfChanged = false;
stopIfChanged = false;
wantedBy = [ "multi-user.target" ];
wants = [ "network-online.target" ];
after = [ "network-online.target" ];
startAt = "hourly";

View file

@ -3,19 +3,13 @@ let
link = config.local.links.forgejo;
in
{
sops.secrets.forgejo.owner = config.services.forgejo.user;
local.links.forgejo = { };
users = {
groups.${config.services.forgejo.group} = { };
users = {
${config.services.forgejo.user} = {
isSystemUser = true;
inherit (config.services.forgejo) group;
extraGroups = [ "postgres" ];
openssh.authorizedKeys.keys = [ config.local.keys.gerg_gerg-desktop ];
};
};
};
users.users.${config.services.forgejo.user}.openssh.authorizedKeys.keys = [
config.local.keys.gerg_gerg-desktop
];
services.forgejo = {
enable = true;
stateDir = "/persist/services/forgejo";
@ -25,15 +19,24 @@ in
DOMAIN = "git.gerg-l.com";
ROOT_URL = "https://git.gerg-l.com/";
LANDING_PAGE = "/explore/repos";
PROTOCOL = link.protocol;
HTTP_ADDR = link.ipv4;
HTTP_PORT = link.port;
};
ui.DEFAULT_THEME = "forgejo-dark";
service.DISABLE_REGISTRATION = true;
database.LOG_SQL = false;
};
database = {
database =
let
dbLink = config.local.links.postgresql;
in
{
type = "postgres";
createDatabase = true;
inherit (dbLink) port;
host = dbLink.hostname;
passwordFile = config.sops.secrets.forgejo.path;
};
};

View file

@ -1,25 +1,33 @@
{ config, ... }:
{ config }:
let
cfg = config.services.immich;
link = config.local.links.immich;
in
{
sops.secrets.immich.owner = cfg.user;
local.links.immich = { };
systemd.tmpfiles.rules = [ "d ${cfg.mediaLocation} - ${cfg.user} ${cfg.group} - -" ];
users.users.${cfg.user}.extraGroups = [ "postgres" ];
services.immich = {
enable = true;
openFirewall = true;
database = {
#secretsFile = config.sops.secrets.immich.path;
database =
let
dbLink = config.local.links.postgresql;
in
{
enable = true;
createDB = true;
inherit (dbLink) port;
#host = dbLink.hostname;
};
mediaLocation = "/persist/services/immich";
machine-learning.enable = true;
settings = null;
inherit (link) port;
host = link.ipv4;
host = link.hostname;
};
local.nginx.proxyVhosts."photos.gerg-l.com" = link.url;

View file

@ -1,4 +1,5 @@
{
lib,
config,
}:
let
@ -14,23 +15,15 @@ in
config = {
BASE_URL = "https://flux.gerg-l.com";
LISTEN_ADDR = link.tuple;
DATABASE_URL =
let
dbLink = config.local.links.postgresql;
in
lib.mkForce "user=miniflux host=${dbLink.hostname} port=${dbLink.portStr} dbname=miniflux sslmode=disable";
};
adminCredentialsFile = config.sops.secrets.minifluxenv.path;
createDatabaseLocally = true;
};
users = {
groups.miniflux.gid = 377;
users = {
miniflux = {
group = "miniflux";
extraGroups = [ "postgres" ];
isSystemUser = true;
uid = 377;
};
${config.services.nginx.user}.extraGroups = [ "miniflux" ];
};
};
local.nginx.proxyVhosts."flux.gerg-l.com" = link.url;
}

View file

@ -9,41 +9,42 @@
};
};
config = {
config =
let
cfg = config.services.nginx;
in
{
local.nginx.defaultVhosts = builtins.mapAttrs (_: v: {
locations."/".proxyPass = v;
}) config.local.nginx.proxyVhosts;
sops.secrets = {
gerg_ssl_key.owner = config.services.nginx.user;
gerg_ssl_cert.owner = config.services.nginx.user;
gerg_ssl_key.owner = cfg.user;
gerg_ssl_cert.owner = cfg.user;
};
security.acme = {
acceptTerms = true;
certs."gerg-l.com" = {
email = "GregLeyda@proton.me";
inherit (cfg) group;
webroot = "/var/lib/acme/acme-challenge";
extraDomainNames = builtins.attrNames config.local.nginx.defaultVhosts;
};
};
fileSystems."/var/lib/acme" = {
device = "/persist/services/acme";
fsType = "none";
options = [ "bind" ];
depends = [
"/persist"
"/var"
systemd.mounts = [
{
what = "/persist/services/acme";
where = "/var/lib/acme";
type = "none";
options = "bind";
}
];
};
users.users.${config.services.nginx.user}.extraGroups = [ "acme" ];
services.nginx = {
enable = true;
recommendedZstdSettings = true;
recommendedGzipSettings = true;
recommendedOptimisation = true;
recommendedProxySettings = true;
recommendedTlsSettings = true;

View file

@ -1,9 +1,22 @@
{ pkgs }:
{
lib,
pkgs,
config,
}:
let
link = config.local.links.postgresql;
in
{
local.links.postgresql.port = 5432;
services.postgresql = {
enable = true;
package = pkgs.postgresql_16;
dataDir = "/persist/services/postgresql";
settings.unix_socket_permissions = "0770";
settings = {
inherit (link) port;
listen_addresses = lib.mkForce link.ipv4;
#unix_socket_directories = "";
};
};
}

View file

@ -22,10 +22,13 @@ in
secret_key = "@SEARXNG_SECRET@";
base_url = "https://search.gerg-l.com";
};
search.formats = [
search = {
default_lang = "en";
formats = [
"html"
"json"
];
};
engines = [
{
name = "bing";

View file

@ -0,0 +1,94 @@
{ link, lavalinkPlugins }:
{
server = {
http2.enabled = false;
port = link.portStr;
address = link.ipv4;
};
lavalink = {
pluginsDir = lavalinkPlugins;
plugins = [
{
dependency = "dev.lavalink.youtube:youtube-plugin:1.11.5";
enabled = true;
snapshot = false;
}
];
server = {
#password = "";
bufferDurationMs = 400;
filters = {
channelMix = true;
distortion = true;
equalizer = true;
karaoke = true;
lowPass = true;
rotation = true;
timescale = true;
tremolo = true;
vibrato = true;
volume = true;
};
frameBufferDurationMs = 5000;
gc-warnings = true;
nonAllocatingFrameBuffer = false;
opusEncodingQuality = 10;
playerUpdateInterval = 5;
resamplingQuality = "LOW";
soundcloudSearchEnabled = true;
sources = {
bandcamp = true;
http = true;
local = false;
nico = true;
soundcloud = true;
twitch = true;
vimeo = true;
youtube = false;
};
trackStuckThresholdMs = 10000;
useSeekGhosting = true;
youtubePlaylistLoadLimit = 6;
youtubeSearchEnabled = true;
};
};
logging = {
file.path = null;
level = {
"dev.lavalink.youtube.http.YoutubeOauth2Handler" = "INFO";
lavalink = "INFO";
root = "INFO";
};
request = {
enabled = true;
includeClientInfo = true;
includeHeaders = false;
includePayload = true;
includeQueryString = true;
maxPayloadLength = 10000;
};
};
metrics.prometheus.enabled = false;
plugins = {
youtube = {
allowDirectPlaylistIds = true;
allowDirectVideoIds = true;
allowSearch = true;
clients = [ "TVHTML5EMBEDDED" ];
enabled = true;
oauth = {
enabled = true;
#refreshToken = "";
};
};
};
sentry = {
dsn = "";
environment = "";
};
}

View file

@ -0,0 +1,146 @@
{
link,
ferretLink,
p,
}:
{
activity = [
{
name = "/help";
status = "online";
type = "listening";
}
];
aliases = {
connect = [ "join" ];
leave = [
"stop"
"bye"
];
play = [ "p" ];
view = [ "v" ];
};
bot_access_user = [ ];
client_id = p."vocard/client_id";
cooldowns = {
connect = [
2
30
];
"playlist view" = [
1
30
];
};
default_controller = {
default_buttons = [
[
"back"
"resume"
"skip"
{ stop = "red"; }
"add"
]
[ "tracks" ]
];
disableButtonText = false;
embeds = {
active = {
author = {
icon_url = "@@bot_icon@@";
name = "Music Controller | @@channel_name@@";
};
color = "@@track_color@@";
description = "**Now Playing: ```[@@track_name@@]```\nLink: [Click Me](@@track_url@@) | Requester: @@requester@@ | DJ: @@dj@@**";
footer.text = "Queue Length: @@queue_length@@ | Duration: @@track_duration@@ | Volume: @@volume@@% {{loop_mode != 'Off' ?? | Repeat: @@loop_mode@@}}";
image = "@@track_thumbnail@@";
};
inactive = {
color = "@@default_embed_color@@";
description = "[Support](@@server_invite_link@@) | [Invite](@@invite_link@@) | [Questionnaire](https://forms.gle/Qm8vjBfg2kp13YGD7)";
image = "https://i.imgur.com/dIFBwU7.png";
title.name = "There are no songs playing right now";
};
};
};
default_max_queue = 1000;
default_voice_status_template = "{{@@track_name@@ != 'None' ?? @@track_source_emoji@@ Now Playing: @@track_name@@ // Waiting for song requests}}";
embed_color = "0xb3b3b3";
genius_token = "YOUR_GENIUS_TOKEN";
ipc_client = {
enable = false;
host = "127.0.0.1";
password = "YOUR_PASSWORD";
port = 8000;
secure = false;
};
logging = {
file = {
enable = false;
path = "./logs";
};
level = {
discord = "INFO";
ipc_client = "INFO";
vocard = "INFO";
};
max-history = 30;
};
lyrics_platform = "lyrist";
mongodb_name = "vocard";
mongodb_url = ferretLink.url;
nodes.DEFAULT = {
host = link.hostname;
identifier = "DEFAULT";
password = p."vocard/password";
inherit (link) port;
secure = false;
};
prefix = "?";
sources_settings = {
apple = {
color = "0xE298C4";
emoji = "<:applemusic:994844332374884413>";
};
bandcamp = {
color = "0x6F98A7";
emoji = "<:bandcamp:864694003811221526>";
};
reddit = {
color = "0xFF5700";
emoji = "<:reddit:996007566863773717>";
};
soundcloud = {
color = "0xFF7700";
emoji = "<:soundcloud:852729280027033632>";
};
spotify = {
color = "0x1DB954";
emoji = "<:spotify:826661996615172146>";
};
tiktok = {
color = "0x74ECE9";
emoji = "<:tiktok:996007689798811698>";
};
twitch = {
color = "0x9B4AFF";
emoji = "<:twitch:852729278285086741>";
};
vimeo = {
color = "0x1ABCEA";
emoji = "<:vimeo:864694001919721473>";
};
youtube = {
color = "0xFF0000";
emoji = "<:youtube:826661982760992778>";
};
"youtube music" = {
color = "0xFF0000";
emoji = "<:youtube:826661982760992778>";
};
};
spotify_client_id = p."vocard/spotify_client_id";
spotify_client_secret = p."vocard/spotify_client_secret";
token = p."vocard/token";
version = "v2.6.9";
}

View file

@ -1,109 +0,0 @@
server: # REST and WS server
port: 2333
address: 0.0.0.0
http2:
enabled: false # Whether to enable HTTP/2 support
plugins:
youtube:
enabled: true
allowSearch: true # Whether "ytsearch:" and "ytmsearch:" can be used.
allowDirectVideoIds: true # Whether just video IDs can match. If false, only complete URLs will be loaded.
allowDirectPlaylistIds: true # Whether just playlist IDs can match. If false, only complete URLs will be loaded.
# The clients to use for track loading. See below for a list of valid clients.
# Clients are queried in the order they are given (so the first client is queried first and so on...)
clients:
- TVHTML5EMBEDDED
oauth:
enabled: true
# Set with env vars
#refreshToken: ""
lavalink:
plugins:
- dependency: "dev.lavalink.youtube:youtube-plugin:1.11.5"
snapshot: false
# setting "enabled: true" is the bare minimum to get OAuth working.
enabled: true
# Set with env vars
#pluginsDir: ""
server:
# Set with env vars
#password: ""
sources:
youtube: false
bandcamp: true
soundcloud: true
twitch: true
vimeo: true
nico: true
http: true
local: false
filters: # All filters are enabled by default
volume: true
equalizer: true
karaoke: true
timescale: true
tremolo: true
vibrato: true
distortion: true
rotation: true
channelMix: true
lowPass: true
nonAllocatingFrameBuffer: false # Setting to true reduces the number of allocations made by each player at the expense of frame rebuilding (e.g. non-instantaneous volume changes)
bufferDurationMs: 400 # The duration of the NAS buffer. Higher values fare better against longer GC pauses. Duration <= 0 to disable JDA-NAS. Minimum of 40ms, lower values may introduce pauses.
frameBufferDurationMs: 5000 # How many milliseconds of audio to keep buffered
opusEncodingQuality: 10 # Opus encoder quality. Valid values range from 0 to 10, where 10 is best quality but is the most expensive on the CPU.
resamplingQuality: LOW # Quality of resampling operations. Valid values are LOW, MEDIUM and HIGH, where HIGH uses the most CPU.
trackStuckThresholdMs: 10000 # The threshold for how long a track can be stuck. A track is stuck if does not return any audio data.
useSeekGhosting: true # Seek ghosting is the effect where whilst a seek is in progress, the audio buffer is read from until empty, or until seek is ready.
youtubePlaylistLoadLimit: 6 # Number of pages at 100 each
playerUpdateInterval: 5 # How frequently to send player updates to clients, in seconds
youtubeSearchEnabled: true
soundcloudSearchEnabled: true
gc-warnings: true
#ratelimit:
#ipBlocks: ["1.0.0.0/8", "..."] # list of ip blocks
#excludedIps: ["...", "..."] # ips which should be explicit excluded from usage by lavalink
#strategy: "RotateOnBan" # RotateOnBan | LoadBalance | NanoSwitch | RotatingNanoSwitch
#searchTriggersFail: true # Whether a search 429 should trigger marking the ip as failing
#retryLimit: -1 # -1 = use default lavaplayer value | 0 = infinity | >0 = retry will happen this numbers times
#youtubeConfig: # Required for avoiding all age restrictions by YouTube, some restricted videos still can be played without.
#email: "" # Email of Google account
#password: "" # Password of Google account
#httpConfig: # Useful for blocking bad-actors from ip-grabbing your music node and attacking it, this way only the http proxy will be attacked
#proxyHost: "localhost" # Hostname of the proxy, (ip or domain)
#proxyPort: 3128 # Proxy port, 3128 is the default for squidProxy
#proxyUser: "" # Optional user for basic authentication fields, leave blank if you don't use basic auth
#proxyPassword: "" # Password for basic authentication
metrics:
prometheus:
enabled: false
endpoint: /metrics
sentry:
dsn: ""
environment: ""
logging:
file:
path: null
level:
root: INFO
lavalink: INFO
dev.lavalink.youtube.http.YoutubeOauth2Handler: INFO
request:
enabled: true
includeClientInfo: true
includeHeaders: false
includeQueryString: true
includePayload: true
maxPayloadLength: 10000
logback:
rollingpolicy:
max-file-size: 1GB
max-history: 30

View file

@ -1,157 +0,0 @@
{
"token": "@token@",
"client_id": "@client_id@",
"spotify_client_id": "@spotify_client_id@",
"spotify_client_secret": "@spotify_client_secret@",
"genius_token": "YOUR_GENIUS_TOKEN",
"mongodb_url": "0.0.0.0",
"mongodb_name": "vocard",
"nodes": {
"DEFAULT": {
"host": "0.0.0.0",
"port": 2333,
"password": "@password@",
"secure": false,
"identifier": "DEFAULT"
}
},
"prefix": "?",
"activity": [
{
"type": "listening",
"name": "/help",
"status": "online"
}
],
"logging": {
"file": {
"path": "./logs",
"enable": false
},
"level": {
"discord": "INFO",
"vocard": "INFO",
"ipc_client": "INFO"
},
"max-history": 30
},
"bot_access_user": [],
"embed_color": "0xb3b3b3",
"default_max_queue": 1000,
"lyrics_platform": "lyrist",
"ipc_client": {
"host": "127.0.0.1",
"port": 8000,
"password": "YOUR_PASSWORD",
"secure": false,
"enable": false
},
"sources_settings": {
"youtube": {
"emoji": "<:youtube:826661982760992778>",
"color": "0xFF0000"
},
"youtube music": {
"emoji": "<:youtube:826661982760992778>",
"color": "0xFF0000"
},
"spotify": {
"emoji": "<:spotify:826661996615172146>",
"color": "0x1DB954"
},
"soundcloud": {
"emoji": "<:soundcloud:852729280027033632>",
"color": "0xFF7700"
},
"twitch": {
"emoji": "<:twitch:852729278285086741>",
"color": "0x9B4AFF"
},
"bandcamp": {
"emoji": "<:bandcamp:864694003811221526>",
"color": "0x6F98A7"
},
"vimeo": {
"emoji": "<:vimeo:864694001919721473>",
"color": "0x1ABCEA"
},
"apple": {
"emoji": "<:applemusic:994844332374884413>",
"color": "0xE298C4"
},
"reddit": {
"emoji": "<:reddit:996007566863773717>",
"color": "0xFF5700"
},
"tiktok": {
"emoji": "<:tiktok:996007689798811698>",
"color": "0x74ECE9"
}
},
"default_controller": {
"embeds": {
"active": {
"description": "**Now Playing: ```[@@track_name@@]```\nLink: [Click Me](@@track_url@@) | Requester: @@requester@@ | DJ: @@dj@@**",
"footer": {
"text": "Queue Length: @@queue_length@@ | Duration: @@track_duration@@ | Volume: @@volume@@% {{loop_mode != 'Off' ?? | Repeat: @@loop_mode@@}}"
},
"image": "@@track_thumbnail@@",
"author": {
"name": "Music Controller | @@channel_name@@",
"icon_url": "@@bot_icon@@"
},
"color": "@@track_color@@"
},
"inactive": {
"title": {
"name": "There are no songs playing right now"
},
"description": "[Support](@@server_invite_link@@) | [Invite](@@invite_link@@) | [Questionnaire](https://forms.gle/Qm8vjBfg2kp13YGD7)",
"image": "https://i.imgur.com/dIFBwU7.png",
"color": "@@default_embed_color@@"
}
},
"default_buttons": [
[
"back",
"resume",
"skip",
{
"stop": "red"
},
"add"
],
[
"tracks"
]
],
"disableButtonText": false
},
"default_voice_status_template": "{{@@track_name@@ != 'None' ?? @@track_source_emoji@@ Now Playing: @@track_name@@ // Waiting for song requests}}",
"cooldowns": {
"connect": [
2,
30
],
"playlist view": [
1,
30
]
},
"aliases": {
"connect": [
"join"
],
"leave": [
"stop",
"bye"
],
"play": [
"p"
],
"view": [
"v"
]
},
"version": "v2.6.9"
}

View file

@ -2,11 +2,22 @@
self',
lib,
config,
pkgs,
}:
let
link = config.local.links.lavalink;
ferretLink = config.local.links.ferretdb;
in
{
local.links = {
lavalink = { };
ferretdb.protocol = "mongodb";
};
sops = {
secrets =
{
ferretdb = { };
lavalink = {
sopsFile = ./secrets.yaml;
restartUnits = [
@ -36,23 +47,12 @@
"vocard.service"
"lavalink.service"
];
content =
builtins.replaceStrings
[
"@token@"
"@client_id@"
"@spotify_client_id@"
"@spotify_client_secret@"
"@password@"
]
(map (x: config.sops.placeholder.${x}) [
"vocard/token"
"vocard/client_id"
"vocard/spotify_client_id"
"vocard/spotify_client_secret"
"vocard/password"
])
(builtins.readFile ./settings.json);
content = builtins.toJSON (
import ./_settings.nix {
inherit link ferretLink;
p = config.sops.placeholder;
}
);
};
};
@ -88,10 +88,16 @@
"network-online.target"
];
environment.LAVALINK_PLUGINS_DIR = self'.packages.lavalinkPlugins;
serviceConfig = {
ExecStart = "${lib.getExe self'.packages.lavalink} --spring.config.location='file:${./application.yml}'";
ExecStart = lib.getExe self'.packages.lavalink;
WorkingDirectory = lib.pipe ./_application.nix [
(lib.flip import {
inherit link;
inherit (self'.packages) lavalinkPlugins;
})
builtins.toJSON
(pkgs.writeTextDir "application.yml")
];
DynamicUser = true;
EnvironmentFile = config.sops.secrets.lavalink.path;
Restart = "on-failure";
@ -100,7 +106,55 @@
};
};
services.ferretdb.enable = true;
services.postgresql = {
ensureDatabases = [ "ferretdb" ];
ensureUsers = [
{
name = "ferretdb";
ensureDBOwnership = true;
}
];
};
systemd.services.ferretdb = {
description = "FerretDB";
after = [ "network.target" ];
wantedBy = [ "multi-user.target" ];
environment = {
FERRETDB_HANDLER = "pg";
FERRETDB_LISTEN_ADDR = ferretLink.tuple;
};
serviceConfig = {
ExecStart =
let
dbLink = config.local.links.postgresql;
in
"${lib.getExe pkgs.ferretdb} --debug-addr='-' --telemetry='disable' --postgresql-url=\"postgres:///ferretdb?user=ferretdb&host=${dbLink.hostname}&port=${dbLink.portStr}&passfile=\${CREDENTIALS_DIRECTORY}/password\"";
Type = "simple";
StateDirectory = "ferretdb";
WorkingDirectory = "%S/ferretdb";
LoadCredential = "password:${config.sops.secrets.ferretdb.path}";
Restart = "on-failure";
ProtectHome = true;
ProtectSystem = "strict";
PrivateTmp = true;
PrivateDevices = true;
ProtectHostname = true;
ProtectClock = true;
ProtectKernelTunables = true;
ProtectKernelModules = true;
ProtectKernelLogs = true;
ProtectControlGroups = true;
NoNewPrivileges = true;
RestrictRealtime = true;
RestrictSUIDSGID = true;
RemoveIPC = true;
PrivateMounts = true;
DynamicUser = true;
};
};
systemd.mounts = [
{

View file

@ -7,11 +7,7 @@
{
local = {
remoteBuild.enable = true;
DM = {
lightdm.enable = true;
autoLogin = true;
loginUser = "media";
};
DM.lightdm.enable = true;
DE.xfce.enable = true;
theming = {
enable = true;
@ -35,6 +31,10 @@
sops.secrets.root.neededForUsers = true;
services.displayManager.autoLogin = {
enable = true;
user = "media";
};
users = {
mutableUsers = false;
users = {

View file

@ -38,62 +38,9 @@
sxhkd = {
wantedBy = [ "graphical-session.target" ];
partOf = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${lib.getExe pkgs.sxhkd} -c /etc/sxhkd/sxhkdrc";
Restart = "always";
RestartSec = 2;
ExecReload = "pkill -usr1 -x $MAINPID";
};
};
picom = {
wantedBy = [ "graphical-session.target" ];
partOf = [ "graphical-session.target" ];
serviceConfig = {
ExecStart = "${lib.getExe pkgs.picom} --backend egl";
Restart = "always";
RestartSec = 2;
ExecReload = "pkill -usr1 -x $MAINPID";
};
};
};
services = {
gvfs.enable = true;
displayManager.defaultSession = "none+dwm";
xserver = {
enable = true;
displayManager = {
sessionCommands = ''
feh --bg-center "${self'.packages.images}/recursion.png"
numlockx
'';
};
windowManager.session = [
{
name = "dwm";
start = ''
update_time () {
while :
do
sleep 1
xsetroot -name "$(date +"%I:%M %p")"
done
}
dont_stop() {
while type dwm >/dev/null ; do dwm && continue || break ; done
}
update_time &
dont_stop &
waitPID=$!
'';
}
];
};
};
environment.etc."sxhkd/sxhkdrc".text = ''
serviceConfig =
let
configFile = pkgs.writeText "sxhkdrc" ''
XF86AudioPlay
playerctl play-pause
XF86AudioPause
@ -123,5 +70,54 @@
super + ctrl + l
xsecurelock
'';
in
{
ExecStart = "${lib.getExe pkgs.sxhkd} -c '${configFile}'";
Restart = "always";
RestartSec = 2;
ExecReload = "pkill -usr1 -x $MAINPID";
};
};
picom = {
wantedBy = [ "graphical-session.target" ];
partOf = [ "graphical-session.target" ];
serviceConfig.ExecStart = "${lib.getExe pkgs.picom} --backend egl";
};
};
services = {
displayManager.defaultSession = "none+dwm";
xserver = {
enable = true;
displayManager.sessionCommands = ''
feh --bg-center "${self'.packages.images}/recursion.png"
numlockx
'';
windowManager.session = [
{
name = "dwm";
start = ''
update_time () {
while :
do
sleep 1
xsetroot -name "$(date +"%I:%M %p")"
done
}
dont_stop() {
while type dwm >/dev/null ; do dwm && continue || break ; done
}
update_time &
dont_stop &
waitPID=$!
'';
}
];
};
};
};
}

View file

@ -8,14 +8,12 @@
config = lib.mkIf config.local.DE.xfce.enable {
environment.systemPackages = [ pkgs.xfce.xfce4-whiskermenu-plugin ];
services = {
xserver = {
services.xserver = {
enable = true;
desktopManager.xfce = {
enable = true;
enableScreensaver = true;
};
};
displayManager.defaultSession = "xfce";
};
};

View file

@ -1,19 +0,0 @@
{ config, lib }:
{
options.local.DM = {
autoLogin = lib.mkEnableOption "";
loginUser = lib.mkOption {
type = lib.types.nullOr lib.types.str;
default = null;
};
};
config = lib.mkIf config.local.DM.autoLogin {
services.displayManager = {
autoLogin = {
enable = true;
user = config.local.DM.loginUser;
};
};
};
}

View file

@ -14,7 +14,7 @@
extraConfig = "minimum-vt=1";
greeters.mini = {
enable = true;
user = config.local.DM.loginUser;
inherit (config.services.displayManager.autoLogin) user;
extraConfig = ''
[greeter]
show-password-label = false

View file

@ -1,5 +1,6 @@
{ pkgs, lib }:
{
services.libinput.mouse.accelProfile = "flat";
services.xserver = {
tty = lib.mkDefault 1;
exportConfiguration = true;

View file

@ -21,6 +21,7 @@
"quiet" # Less log messages
"systemd.show_status=auto" # Only show systemd errors
"udev.log_level=3" # Only show udev errors
"plymouth.use-simpledrm" # Faster plymouth splash
"splash" # Show splash
];
consoleLogLevel = 3; # Only errors

View file

@ -51,6 +51,7 @@
"read-only-local-store"
"recursive-nix"
"configurable-impure-env"
"pipe-operators"
];
auto-optimise-store = true;
warn-dirty = false;